diff options
Diffstat (limited to 'nss/lib/jar/jarfile.c')
-rw-r--r-- | nss/lib/jar/jarfile.c | 968 |
1 files changed, 483 insertions, 485 deletions
diff --git a/nss/lib/jar/jarfile.c b/nss/lib/jar/jarfile.c index 96da4d7..e2470a1 100644 --- a/nss/lib/jar/jarfile.c +++ b/nss/lib/jar/jarfile.c @@ -20,7 +20,7 @@ #include "sys/stat.h" #endif -#include "sechash.h" /* for HASH_GetHashObject() */ +#include "sechash.h" /* for HASH_GetHashObject() */ PR_STATIC_ASSERT(46 == sizeof(struct ZipCentral)); PR_STATIC_ASSERT(30 == sizeof(struct ZipLocal)); @@ -28,50 +28,48 @@ PR_STATIC_ASSERT(22 == sizeof(struct ZipEnd)); PR_STATIC_ASSERT(512 == sizeof(union TarEntry)); /* extracting */ -static int +static int jar_guess_jar(const char *filename, JAR_FILE fp); -static int -jar_inflate_memory(unsigned int method, long *length, long expected_out_len, +static int +jar_inflate_memory(unsigned int method, long *length, long expected_out_len, char **data); -static int +static int jar_physical_extraction(JAR_FILE fp, char *outpath, unsigned long offset, unsigned long length); -static int +static int jar_physical_inflate(JAR_FILE fp, char *outpath, unsigned long offset, unsigned long length, unsigned int method); -static int +static int jar_verify_extract(JAR *jar, char *path, char *physical_path); static JAR_Physical * jar_get_physical(JAR *jar, char *pathname); -static int +static int jar_extract_manifests(JAR *jar, jarArch format, JAR_FILE fp); -static int +static int jar_extract_mf(JAR *jar, jarArch format, JAR_FILE fp, char *ext); - /* indexing */ -static int +static int jar_gen_index(JAR *jar, jarArch format, JAR_FILE fp); -static int +static int jar_listtar(JAR *jar, JAR_FILE fp); -static int +static int jar_listzip(JAR *jar, JAR_FILE fp); - /* conversions */ -static int +static int dosdate(char *date, const char *s); -static int +static int dostime(char *time, const char *s); #ifdef NSS_X86_OR_X64 @@ -79,8 +77,8 @@ dostime(char *time, const char *s); #if defined(__GNUC__) && !defined(NSS_NO_GCC48) #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif -#define x86ShortToUint32(ii) ((const PRUint32)*((const PRUint16 *)(ii))) -#define x86LongToUint32(ii) (*(const PRUint32 *)(ii)) +#define x86ShortToUint32(ii) ((const PRUint32) * ((const PRUint16 *)(ii))) +#define x86LongToUint32(ii) (*(const PRUint32 *)(ii)) #else static PRUint32 x86ShortToUint32(const void *ii); @@ -89,7 +87,7 @@ static PRUint32 x86LongToUint32(const void *ll); #endif -static long +static long octalToLong(const char *s); /* @@ -100,33 +98,33 @@ octalToLong(const char *s); * the archive file, and do whatever nastiness. * */ -int +int JAR_pass_archive(JAR *jar, jarArch format, char *filename, const char *url) { JAR_FILE fp; int status = 0; if (filename == NULL) - return JAR_ERR_GENERAL; + return JAR_ERR_GENERAL; - if ((fp = JAR_FOPEN (filename, "rb")) != NULL) { - if (format == jarArchGuess) - format = (jarArch)jar_guess_jar (filename, fp); + if ((fp = JAR_FOPEN(filename, "rb")) != NULL) { + if (format == jarArchGuess) + format = (jarArch)jar_guess_jar(filename, fp); - jar->format = format; - jar->url = url ? PORT_Strdup (url) : NULL; - jar->filename = PORT_Strdup (filename); + jar->format = format; + jar->url = url ? PORT_Strdup(url) : NULL; + jar->filename = PORT_Strdup(filename); - status = jar_gen_index (jar, format, fp); - if (status == 0) - status = jar_extract_manifests (jar, format, fp); + status = jar_gen_index(jar, format, fp); + if (status == 0) + status = jar_extract_manifests(jar, format, fp); - JAR_FCLOSE (fp); - if (status < 0) - return status; + JAR_FCLOSE(fp); + if (status < 0) + return status; - /* people were expecting it this way */ - return jar->valid; + /* people were expecting it this way */ + return jar->valid; } /* file not found */ return JAR_ERR_FNF; @@ -138,38 +136,38 @@ JAR_pass_archive(JAR *jar, jarArch format, char *filename, const char *url) * Same as JAR_pass_archive, but doesn't parse signatures. * */ -int -JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename, +int +JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename, const char *url) { JAR_FILE fp; int status = 0; if (filename == NULL) { - return JAR_ERR_GENERAL; + return JAR_ERR_GENERAL; } - if ((fp = JAR_FOPEN (filename, "rb")) != NULL) { - if (format == jarArchGuess) { - format = (jarArch)jar_guess_jar (filename, fp); - } + if ((fp = JAR_FOPEN(filename, "rb")) != NULL) { + if (format == jarArchGuess) { + format = (jarArch)jar_guess_jar(filename, fp); + } - jar->format = format; - jar->url = url ? PORT_Strdup (url) : NULL; - jar->filename = PORT_Strdup (filename); + jar->format = format; + jar->url = url ? PORT_Strdup(url) : NULL; + jar->filename = PORT_Strdup(filename); - status = jar_gen_index (jar, format, fp); - if (status == 0) { - status = jar_extract_mf(jar, format, fp, "mf"); - } + status = jar_gen_index(jar, format, fp); + if (status == 0) { + status = jar_extract_mf(jar, format, fp, "mf"); + } - JAR_FCLOSE (fp); - if (status < 0) { - return status; - } + JAR_FCLOSE(fp); + if (status < 0) { + return status; + } - /* people were expecting it this way */ - return jar->valid; + /* people were expecting it this way */ + return jar->valid; } /* file not found */ return JAR_ERR_FNF; @@ -184,52 +182,51 @@ JAR_pass_archive_unverified(JAR *jar, jarArch format, char *filename, * */ -int +int JAR_verified_extract(JAR *jar, char *path, char *outpath) { - int status = JAR_extract (jar, path, outpath); + int status = JAR_extract(jar, path, outpath); if (status >= 0) - return jar_verify_extract(jar, path, outpath); + return jar_verify_extract(jar, path, outpath); return status; } -int +int JAR_extract(JAR *jar, char *path, char *outpath) { int result; JAR_Physical *phy; if (jar->fp == NULL && jar->filename) { - jar->fp = (FILE*)JAR_FOPEN (jar->filename, "rb"); + jar->fp = (FILE *)JAR_FOPEN(jar->filename, "rb"); } if (jar->fp == NULL) { - /* file not found */ - return JAR_ERR_FNF; + /* file not found */ + return JAR_ERR_FNF; } - phy = jar_get_physical (jar, path); + phy = jar_get_physical(jar, path); if (phy) { - if (phy->compression != 0 && phy->compression != 8) { - /* unsupported compression method */ - result = JAR_ERR_CORRUPT; - } - if (phy->compression == 0) { - result = jar_physical_extraction - ((PRFileDesc*)jar->fp, outpath, phy->offset, phy->length); - } else { - result = jar_physical_inflate((PRFileDesc*)jar->fp, outpath, - phy->offset, phy->length, - (unsigned int) phy->compression); - } + if (phy->compression != 0 && phy->compression != 8) { + /* unsupported compression method */ + result = JAR_ERR_CORRUPT; + } + if (phy->compression == 0) { + result = jar_physical_extraction((PRFileDesc *)jar->fp, outpath, phy->offset, phy->length); + } else { + result = jar_physical_inflate((PRFileDesc *)jar->fp, outpath, + phy->offset, phy->length, + (unsigned int)phy->compression); + } #if defined(XP_UNIX) || defined(XP_BEOS) - if (phy->mode) - chmod (outpath, 0400 | (mode_t) phy->mode); + if (phy->mode) + chmod(outpath, 0400 | (mode_t)phy->mode); #endif } else { - /* pathname not found in archive */ - result = JAR_ERR_PNF; + /* pathname not found in archive */ + result = JAR_ERR_PNF; } return result; } @@ -245,7 +242,7 @@ JAR_extract(JAR *jar, char *path, char *outpath) #define CHUNK 32768 -static int +static int jar_physical_extraction(JAR_FILE fp, char *outpath, unsigned long offset, unsigned long length) { @@ -254,31 +251,31 @@ jar_physical_extraction(JAR_FILE fp, char *outpath, unsigned long offset, int status = 0; if (buffer == NULL) - return JAR_ERR_MEMORY; - - if ((out = JAR_FOPEN (outpath, "wb")) != NULL) { - unsigned long at = 0; - - JAR_FSEEK (fp, offset, (PRSeekWhence)0); - while (at < length) { - long chunk = (at + CHUNK <= length) ? CHUNK : length - at; - if (JAR_FREAD (fp, buffer, chunk) != chunk) { - status = JAR_ERR_DISK; - break; - } - at += chunk; - if (JAR_FWRITE (out, buffer, chunk) < chunk) { - /* most likely a disk full error */ - status = JAR_ERR_DISK; - break; - } - } - JAR_FCLOSE (out); + return JAR_ERR_MEMORY; + + if ((out = JAR_FOPEN(outpath, "wb")) != NULL) { + unsigned long at = 0; + + JAR_FSEEK(fp, offset, (PRSeekWhence)0); + while (at < length) { + long chunk = (at + CHUNK <= length) ? CHUNK : length - at; + if (JAR_FREAD(fp, buffer, chunk) != chunk) { + status = JAR_ERR_DISK; + break; + } + at += chunk; + if (JAR_FWRITE(out, buffer, chunk) < chunk) { + /* most likely a disk full error */ + status = JAR_ERR_DISK; + break; + } + } + JAR_FCLOSE(out); } else { - /* error opening output file */ - status = JAR_ERR_DISK; + /* error opening output file */ + status = JAR_ERR_DISK; } - PORT_Free (buffer); + PORT_Free(buffer); return status; } @@ -294,7 +291,7 @@ jar_physical_extraction(JAR_FILE fp, char *outpath, unsigned long offset, #define ICHUNK 8192 #define OCHUNK 32768 -static int +static int jar_physical_inflate(JAR_FILE fp, char *outpath, unsigned long offset, unsigned long length, unsigned int method) { @@ -305,77 +302,77 @@ jar_physical_inflate(JAR_FILE fp, char *outpath, unsigned long offset, unsigned /* Raw inflate in zlib 1.1.4 needs an extra dummy byte at the end */ if ((inbuf = (char *)PORT_ZAlloc(ICHUNK + 1)) == NULL) - return JAR_ERR_MEMORY; + return JAR_ERR_MEMORY; if ((outbuf = (char *)PORT_ZAlloc(OCHUNK)) == NULL) { - PORT_Free (inbuf); - return JAR_ERR_MEMORY; + PORT_Free(inbuf); + return JAR_ERR_MEMORY; } - PORT_Memset (&zs, 0, sizeof (zs)); - status = inflateInit2 (&zs, -MAX_WBITS); + PORT_Memset(&zs, 0, sizeof(zs)); + status = inflateInit2(&zs, -MAX_WBITS); if (status != Z_OK) { - PORT_Free (inbuf); - PORT_Free (outbuf); - return JAR_ERR_GENERAL; + PORT_Free(inbuf); + PORT_Free(outbuf); + return JAR_ERR_GENERAL; } - if ((out = JAR_FOPEN (outpath, "wb")) != NULL) { - unsigned long at = 0; - - JAR_FSEEK (fp, offset, (PRSeekWhence)0); - while (at < length) { - unsigned long chunk = (at + ICHUNK <= length) ? ICHUNK : length - at; - unsigned long tin; - - if (JAR_FREAD (fp, inbuf, chunk) != chunk) { - /* incomplete read */ - JAR_FCLOSE (out); - PORT_Free (inbuf); - PORT_Free (outbuf); - return JAR_ERR_CORRUPT; - } - at += chunk; - if (at == length) { - /* add an extra dummy byte at the end */ - inbuf[chunk++] = 0xDD; - } - zs.next_in = (Bytef *) inbuf; - zs.avail_in = chunk; - zs.avail_out = OCHUNK; - tin = zs.total_in; - while ((zs.total_in - tin < chunk) || (zs.avail_out == 0)) { - unsigned long prev_total = zs.total_out; - unsigned long ochunk; - - zs.next_out = (Bytef *) outbuf; - zs.avail_out = OCHUNK; - status = inflate (&zs, Z_NO_FLUSH); - if (status != Z_OK && status != Z_STREAM_END) { - /* error during decompression */ - JAR_FCLOSE (out); - PORT_Free (inbuf); - PORT_Free (outbuf); - return JAR_ERR_CORRUPT; - } - ochunk = zs.total_out - prev_total; - if (JAR_FWRITE (out, outbuf, ochunk) < (long)ochunk) { - /* most likely a disk full error */ - status = JAR_ERR_DISK; - break; - } - if (status == Z_STREAM_END) - break; - } - } - JAR_FCLOSE (out); - status = inflateEnd (&zs); + if ((out = JAR_FOPEN(outpath, "wb")) != NULL) { + unsigned long at = 0; + + JAR_FSEEK(fp, offset, (PRSeekWhence)0); + while (at < length) { + unsigned long chunk = (at + ICHUNK <= length) ? ICHUNK : length - at; + unsigned long tin; + + if (JAR_FREAD(fp, inbuf, chunk) != chunk) { + /* incomplete read */ + JAR_FCLOSE(out); + PORT_Free(inbuf); + PORT_Free(outbuf); + return JAR_ERR_CORRUPT; + } + at += chunk; + if (at == length) { + /* add an extra dummy byte at the end */ + inbuf[chunk++] = 0xDD; + } + zs.next_in = (Bytef *)inbuf; + zs.avail_in = chunk; + zs.avail_out = OCHUNK; + tin = zs.total_in; + while ((zs.total_in - tin < chunk) || (zs.avail_out == 0)) { + unsigned long prev_total = zs.total_out; + unsigned long ochunk; + + zs.next_out = (Bytef *)outbuf; + zs.avail_out = OCHUNK; + status = inflate(&zs, Z_NO_FLUSH); + if (status != Z_OK && status != Z_STREAM_END) { + /* error during decompression */ + JAR_FCLOSE(out); + PORT_Free(inbuf); + PORT_Free(outbuf); + return JAR_ERR_CORRUPT; + } + ochunk = zs.total_out - prev_total; + if (JAR_FWRITE(out, outbuf, ochunk) < (long)ochunk) { + /* most likely a disk full error */ + status = JAR_ERR_DISK; + break; + } + if (status == Z_STREAM_END) + break; + } + } + JAR_FCLOSE(out); + status = inflateEnd(&zs); } else { - /* error opening output file */ - status = JAR_ERR_DISK; + /* error opening output file */ + status = JAR_ERR_DISK; } - PORT_Free (inbuf); - PORT_Free (outbuf); + PORT_Free(inbuf); + PORT_Free(outbuf); return status; } @@ -386,44 +383,44 @@ jar_physical_inflate(JAR_FILE fp, char *outpath, unsigned long offset, unsigned * and thus appears to operate inplace to the caller. * */ -static int -jar_inflate_memory(unsigned int method, long *length, long expected_out_len, +static int +jar_inflate_memory(unsigned int method, long *length, long expected_out_len, char **data) { - char *inbuf = *data; - char *outbuf = (char*)PORT_ZAlloc(expected_out_len); - long insz = *length; + char *inbuf = *data; + char *outbuf = (char *)PORT_ZAlloc(expected_out_len); + long insz = *length; int status; z_stream zs; if (outbuf == NULL) - return JAR_ERR_MEMORY; + return JAR_ERR_MEMORY; PORT_Memset(&zs, 0, sizeof zs); - status = inflateInit2 (&zs, -MAX_WBITS); + status = inflateInit2(&zs, -MAX_WBITS); if (status < 0) { - /* error initializing zlib stream */ - PORT_Free (outbuf); - return JAR_ERR_GENERAL; + /* error initializing zlib stream */ + PORT_Free(outbuf); + return JAR_ERR_GENERAL; } - zs.next_in = (Bytef *) inbuf; - zs.next_out = (Bytef *) outbuf; + zs.next_in = (Bytef *)inbuf; + zs.next_out = (Bytef *)outbuf; zs.avail_in = insz; zs.avail_out = expected_out_len; - status = inflate (&zs, Z_FINISH); + status = inflate(&zs, Z_FINISH); if (status != Z_OK && status != Z_STREAM_END) { - /* error during deflation */ - PORT_Free (outbuf); - return JAR_ERR_GENERAL; + /* error during deflation */ + PORT_Free(outbuf); + return JAR_ERR_GENERAL; } - status = inflateEnd (&zs); + status = inflateEnd(&zs); if (status != Z_OK) { - /* error during deflation */ - PORT_Free (outbuf); - return JAR_ERR_GENERAL; + /* error during deflation */ + PORT_Free(outbuf); + return JAR_ERR_GENERAL; } PORT_Free(*data); *data = outbuf; @@ -437,16 +434,16 @@ jar_inflate_memory(unsigned int method, long *length, long expected_out_len, * Validate signature on the freshly extracted file. * */ -static int +static int jar_verify_extract(JAR *jar, char *path, char *physical_path) { int status; JAR_Digest dig; - PORT_Memset (&dig, 0, sizeof dig); - status = JAR_digest_file (physical_path, &dig); + PORT_Memset(&dig, 0, sizeof dig); + status = JAR_digest_file(physical_path, &dig); if (!status) - status = JAR_verify_digest (jar, path, &dig); + status = JAR_verify_digest(jar, path, &dig); return status; } @@ -463,19 +460,19 @@ jar_get_physical(JAR *jar, char *pathname) ZZLink *link; ZZList *list = jar->phy; - if (ZZ_ListEmpty (list)) - return NULL; + if (ZZ_ListEmpty(list)) + return NULL; - for (link = ZZ_ListHead (list); - !ZZ_ListIterDone (list, link); + for (link = ZZ_ListHead(list); + !ZZ_ListIterDone(list, link); link = link->next) { - JAR_Item *it = link->thing; + JAR_Item *it = link->thing; - if (it->type == jarTypePhy && - it->pathname && !PORT_Strcmp (it->pathname, pathname)) { - JAR_Physical *phy = (JAR_Physical *)it->data; - return phy; - } + if (it->type == jarTypePhy && + it->pathname && !PORT_Strcmp(it->pathname, pathname)) { + JAR_Physical *phy = (JAR_Physical *)it->data; + return phy; + } } return NULL; } @@ -487,29 +484,29 @@ jar_get_physical(JAR *jar, char *pathname) * from an open archive file whose contents are known. * */ -static int +static int jar_extract_manifests(JAR *jar, jarArch format, JAR_FILE fp) { int status, signatures; if (format != jarArchZip && format != jarArchTar) - return JAR_ERR_CORRUPT; + return JAR_ERR_CORRUPT; - if ((status = jar_extract_mf (jar, format, fp, "mf")) < 0) - return status; + if ((status = jar_extract_mf(jar, format, fp, "mf")) < 0) + return status; if (!status) - return JAR_ERR_ORDER; - if ((status = jar_extract_mf (jar, format, fp, "sf")) < 0) - return status; + return JAR_ERR_ORDER; + if ((status = jar_extract_mf(jar, format, fp, "sf")) < 0) + return status; if (!status) - return JAR_ERR_ORDER; - if ((status = jar_extract_mf (jar, format, fp, "rsa")) < 0) - return status; + return JAR_ERR_ORDER; + if ((status = jar_extract_mf(jar, format, fp, "rsa")) < 0) + return status; signatures = status; - if ((status = jar_extract_mf (jar, format, fp, "dsa")) < 0) - return status; + if ((status = jar_extract_mf(jar, format, fp, "dsa")) < 0) + return status; if (!(signatures += status)) - return JAR_ERR_SIG; + return JAR_ERR_SIG; return 0; } @@ -521,101 +518,100 @@ jar_extract_manifests(JAR *jar, jarArch format, JAR_FILE fp) * longer important when zipping jar files. * */ -static int +static int jar_extract_mf(JAR *jar, jarArch format, JAR_FILE fp, char *ext) { ZZLink *link; ZZList *list = jar->phy; int ret = 0; - if (ZZ_ListEmpty (list)) - return JAR_ERR_PNF; + if (ZZ_ListEmpty(list)) + return JAR_ERR_PNF; - for (link = ZZ_ListHead (list); - ret >= 0 && !ZZ_ListIterDone (list, link); + for (link = ZZ_ListHead(list); + ret >= 0 && !ZZ_ListIterDone(list, link); link = link->next) { - JAR_Item *it = link->thing; - - if (it->type == jarTypePhy && - !PORT_Strncmp (it->pathname, "META-INF", 8)) - { - JAR_Physical *phy = (JAR_Physical *) it->data; - char *fn = it->pathname + 8; - char *e; - char *manifest; - long length; - int num, status; - - if (PORT_Strlen (it->pathname) < 8) - continue; - - if (*fn == '/' || *fn == '\\') - fn++; - if (*fn == 0) { - /* just a directory entry */ - continue; - } - - /* skip to extension */ - for (e = fn; *e && *e != '.'; e++) - /* yip */ ; - - /* and skip dot */ - if (*e == '.') - e++; - if (PORT_Strcasecmp (ext, e)) { - /* not the right extension */ - continue; - } - if (phy->length == 0 || phy->length > 0xFFFF) { - /* manifest files cannot be zero length or too big! */ - /* the 0xFFFF limit is per J2SE SDK */ - return JAR_ERR_CORRUPT; - } - - /* Read in the manifest and parse it */ - /* Raw inflate in zlib 1.1.4 needs an extra dummy byte at the end */ - manifest = (char *)PORT_ZAlloc(phy->length + 1); - if (!manifest) - return JAR_ERR_MEMORY; - - JAR_FSEEK (fp, phy->offset, (PRSeekWhence)0); - num = JAR_FREAD (fp, manifest, phy->length); - if (num != phy->length) { - /* corrupt archive file */ - PORT_Free (manifest); - return JAR_ERR_CORRUPT; - } - - if (phy->compression == 8) { - length = phy->length; - /* add an extra dummy byte at the end */ - manifest[length++] = 0xDD; - status = jar_inflate_memory((unsigned int)phy->compression, - &length, - phy->uncompressed_length, - &manifest); - if (status < 0) { - PORT_Free (manifest); - return status; - } - } else if (phy->compression) { - /* unsupported compression method */ - PORT_Free (manifest); - return JAR_ERR_CORRUPT; - } else - length = phy->length; - - status = JAR_parse_manifest(jar, manifest, length, - it->pathname, "url"); - PORT_Free (manifest); - if (status < 0) - ret = status; - else - ++ret; - } else if (it->type == jarTypePhy) { - /* ordinary file */ - } + JAR_Item *it = link->thing; + + if (it->type == jarTypePhy && + !PORT_Strncmp(it->pathname, "META-INF", 8)) { + JAR_Physical *phy = (JAR_Physical *)it->data; + char *fn = it->pathname + 8; + char *e; + char *manifest; + long length; + int num, status; + + if (PORT_Strlen(it->pathname) < 8) + continue; + + if (*fn == '/' || *fn == '\\') + fn++; + if (*fn == 0) { + /* just a directory entry */ + continue; + } + + /* skip to extension */ + for (e = fn; *e && *e != '.'; e++) + /* yip */; + + /* and skip dot */ + if (*e == '.') + e++; + if (PORT_Strcasecmp(ext, e)) { + /* not the right extension */ + continue; + } + if (phy->length == 0 || phy->length > 0xFFFF) { + /* manifest files cannot be zero length or too big! */ + /* the 0xFFFF limit is per J2SE SDK */ + return JAR_ERR_CORRUPT; + } + + /* Read in the manifest and parse it */ + /* Raw inflate in zlib 1.1.4 needs an extra dummy byte at the end */ + manifest = (char *)PORT_ZAlloc(phy->length + 1); + if (!manifest) + return JAR_ERR_MEMORY; + + JAR_FSEEK(fp, phy->offset, (PRSeekWhence)0); + num = JAR_FREAD(fp, manifest, phy->length); + if (num != phy->length) { + /* corrupt archive file */ + PORT_Free(manifest); + return JAR_ERR_CORRUPT; + } + + if (phy->compression == 8) { + length = phy->length; + /* add an extra dummy byte at the end */ + manifest[length++] = 0xDD; + status = jar_inflate_memory((unsigned int)phy->compression, + &length, + phy->uncompressed_length, + &manifest); + if (status < 0) { + PORT_Free(manifest); + return status; + } + } else if (phy->compression) { + /* unsupported compression method */ + PORT_Free(manifest); + return JAR_ERR_CORRUPT; + } else + length = phy->length; + + status = JAR_parse_manifest(jar, manifest, length, + it->pathname, "url"); + PORT_Free(manifest); + if (status < 0) + ret = status; + else + ++ret; + } else if (it->type == jarTypePhy) { + /* ordinary file */ + } } return ret; } @@ -627,26 +623,26 @@ jar_extract_mf(JAR *jar, jarArch format, JAR_FILE fp, char *ext) * known archive files. Right now .ZIP and .TAR * */ -static int +static int jar_gen_index(JAR *jar, jarArch format, JAR_FILE fp) { int result = JAR_ERR_CORRUPT; - JAR_FSEEK (fp, 0, (PRSeekWhence)0); + JAR_FSEEK(fp, 0, (PRSeekWhence)0); switch (format) { - case jarArchZip: - result = jar_listzip (jar, fp); - break; + case jarArchZip: + result = jar_listzip(jar, fp); + break; - case jarArchTar: - result = jar_listtar (jar, fp); - break; + case jarArchTar: + result = jar_listtar(jar, fp); + break; - case jarArchGuess: - case jarArchNone: - return JAR_ERR_GENERAL; + case jarArchGuess: + case jarArchNone: + return JAR_ERR_GENERAL; } - JAR_FSEEK (fp, 0, (PRSeekWhence)0); + JAR_FSEEK(fp, 0, (PRSeekWhence)0); return result; } @@ -657,15 +653,15 @@ jar_gen_index(JAR *jar, jarArch format, JAR_FILE fp) * style .ZIP file into the JAR linked list. * */ -static int +static int jar_listzip(JAR *jar, JAR_FILE fp) { - ZZLink *ent; - JAR_Item *it; - JAR_Physical *phy; - struct ZipLocal *Local = PORT_ZNew(struct ZipLocal); + ZZLink *ent; + JAR_Item *it = NULL; + JAR_Physical *phy = NULL; + struct ZipLocal *Local = PORT_ZNew(struct ZipLocal); struct ZipCentral *Central = PORT_ZNew(struct ZipCentral); - struct ZipEnd *End = PORT_ZNew(struct ZipEnd); + struct ZipEnd *End = PORT_ZNew(struct ZipEnd); int err = 0; long pos = 0L; @@ -677,139 +673,141 @@ jar_listzip(JAR *jar, JAR_FILE fp) char sig[4]; if (!Local || !Central || !End) { - /* out of memory */ - err = JAR_ERR_MEMORY; - goto loser; + /* out of memory */ + err = JAR_ERR_MEMORY; + goto loser; } while (1) { - PRUint32 sigVal; - JAR_FSEEK (fp, pos, (PRSeekWhence)0); - - if (JAR_FREAD(fp, sig, sizeof sig) != sizeof sig) { - /* zip file ends prematurely */ - err = JAR_ERR_CORRUPT; - goto loser; - } - - JAR_FSEEK (fp, pos, (PRSeekWhence)0); - sigVal = x86LongToUint32(sig); - if (sigVal == LSIG) { - JAR_FREAD (fp, Local, sizeof *Local); - - filename_len = x86ShortToUint32(Local->filename_len); - extra_len = x86ShortToUint32(Local->extrafield_len); - if (filename_len >= JAR_SIZE) { - /* corrupt zip file */ - err = JAR_ERR_CORRUPT; - goto loser; - } - - if (JAR_FREAD (fp, filename, filename_len) != filename_len) { - /* truncated archive file */ - err = JAR_ERR_CORRUPT; - goto loser; - } - filename [filename_len] = 0; - /* Add this to our jar chain */ - phy = PORT_ZNew(JAR_Physical); - if (phy == NULL) { - err = JAR_ERR_MEMORY; - goto loser; - } - - /* We will index any file that comes our way, but when it comes - to actually extraction, compression must be 0 or 8 */ - compression = x86ShortToUint32(Local->method); - phy->compression = (compression <= 255) ? compression : 222; - /* XXX 222 is bad magic. */ - - phy->offset = pos + (sizeof *Local) + filename_len + extra_len; - phy->length = x86LongToUint32(Local->size); - phy->uncompressed_length = x86LongToUint32(Local->orglen); - - dosdate (date, Local->date); - dostime (time, Local->time); - - it = PORT_ZNew(JAR_Item); - if (it == NULL) { - err = JAR_ERR_MEMORY; - goto loser; - } - - it->pathname = PORT_Strdup(filename); - it->type = jarTypePhy; - it->data = (unsigned char *) phy; - it->size = sizeof (JAR_Physical); - - ent = ZZ_NewLink (it); - if (ent == NULL) { - err = JAR_ERR_MEMORY; - goto loser; - } - - ZZ_AppendLink (jar->phy, ent); - pos = phy->offset + phy->length; - } else if (sigVal == CSIG) { - unsigned int attr = 0; - if (JAR_FREAD(fp, Central, sizeof *Central) != sizeof *Central) { - /* apparently truncated archive */ - err = JAR_ERR_CORRUPT; - goto loser; - } + PRUint32 sigVal; + JAR_FSEEK(fp, pos, (PRSeekWhence)0); + + if (JAR_FREAD(fp, sig, sizeof sig) != sizeof sig) { + /* zip file ends prematurely */ + err = JAR_ERR_CORRUPT; + goto loser; + } + + JAR_FSEEK(fp, pos, (PRSeekWhence)0); + sigVal = x86LongToUint32(sig); + if (sigVal == LSIG) { + JAR_FREAD(fp, Local, sizeof *Local); + + filename_len = x86ShortToUint32(Local->filename_len); + extra_len = x86ShortToUint32(Local->extrafield_len); + if (filename_len >= JAR_SIZE) { + /* corrupt zip file */ + err = JAR_ERR_CORRUPT; + goto loser; + } + + if (JAR_FREAD(fp, filename, filename_len) != filename_len) { + /* truncated archive file */ + err = JAR_ERR_CORRUPT; + goto loser; + } + filename[filename_len] = 0; + /* Add this to our jar chain */ + phy = PORT_ZNew(JAR_Physical); + if (phy == NULL) { + err = JAR_ERR_MEMORY; + goto loser; + } + + /* We will index any file that comes our way, but when it comes + to actually extraction, compression must be 0 or 8 */ + compression = x86ShortToUint32(Local->method); + phy->compression = (compression <= 255) ? compression : 222; + /* XXX 222 is bad magic. */ + + phy->offset = pos + (sizeof *Local) + filename_len + extra_len; + phy->length = x86LongToUint32(Local->size); + phy->uncompressed_length = x86LongToUint32(Local->orglen); + + dosdate(date, Local->date); + dostime(time, Local->time); + + it = PORT_ZNew(JAR_Item); + if (it == NULL) { + err = JAR_ERR_MEMORY; + goto loser; + } + + it->pathname = PORT_Strdup(filename); + it->type = jarTypePhy; + it->data = (unsigned char *)phy; + it->size = sizeof(JAR_Physical); + + ent = ZZ_NewLink(it); + if (ent == NULL) { + err = JAR_ERR_MEMORY; + goto loser; + } + + ZZ_AppendLink(jar->phy, ent); + pos = phy->offset + phy->length; + } else if (sigVal == CSIG) { + unsigned int attr = 0; + if (JAR_FREAD(fp, Central, sizeof *Central) != sizeof *Central) { + /* apparently truncated archive */ + err = JAR_ERR_CORRUPT; + goto loser; + } #if defined(XP_UNIX) || defined(XP_BEOS) - /* with unix we need to locate any bits from - the protection mask in the external attributes. */ - attr = Central->external_attributes [2]; /* magic */ - if (attr) { - /* we have to read the filename, again */ - filename_len = x86ShortToUint32(Central->filename_len); - if (filename_len >= JAR_SIZE) { - /* corrupt in central directory */ - err = JAR_ERR_CORRUPT; - goto loser; - } - - if (JAR_FREAD(fp, filename, filename_len) != filename_len) { - /* truncated in central directory */ - err = JAR_ERR_CORRUPT; - goto loser; - } - filename [filename_len] = 0; - - /* look up this name again */ - phy = jar_get_physical (jar, filename); - if (phy) { - /* always allow access by self */ - phy->mode = 0400 | attr; - } - } + /* with unix we need to locate any bits from + the protection mask in the external attributes. */ + attr = Central->external_attributes[2]; /* magic */ + if (attr) { + /* we have to read the filename, again */ + filename_len = x86ShortToUint32(Central->filename_len); + if (filename_len >= JAR_SIZE) { + /* corrupt in central directory */ + err = JAR_ERR_CORRUPT; + goto loser; + } + + if (JAR_FREAD(fp, filename, filename_len) != filename_len) { + /* truncated in central directory */ + err = JAR_ERR_CORRUPT; + goto loser; + } + filename[filename_len] = 0; + + /* look up this name again */ + phy = jar_get_physical(jar, filename); + if (phy) { + /* always allow access by self */ + phy->mode = 0400 | attr; + } + } #endif - pos += sizeof(struct ZipCentral) - + x86ShortToUint32(Central->filename_len) - + x86ShortToUint32(Central->commentfield_len) - + x86ShortToUint32(Central->extrafield_len); - } else if (sigVal == ESIG) { - if (JAR_FREAD(fp, End, sizeof *End) != sizeof *End) { - err = JAR_ERR_CORRUPT; - goto loser; - } - break; - } else { - /* garbage in archive */ - err = JAR_ERR_CORRUPT; - goto loser; - } + pos += sizeof(struct ZipCentral) + + x86ShortToUint32(Central->filename_len) + + x86ShortToUint32(Central->commentfield_len) + + x86ShortToUint32(Central->extrafield_len); + } else if (sigVal == ESIG) { + if (JAR_FREAD(fp, End, sizeof *End) != sizeof *End) { + err = JAR_ERR_CORRUPT; + goto loser; + } + break; + } else { + /* garbage in archive */ + err = JAR_ERR_CORRUPT; + goto loser; + } } loser: - if (Local) - PORT_Free(Local); - if (Central) - PORT_Free(Central); - if (End) - PORT_Free(End); + if (Local) + PORT_Free(Local); + if (phy && it == NULL) + PORT_Free(phy); + if (Central) + PORT_Free(Central); + if (End) + PORT_Free(End); return err; } @@ -820,7 +818,7 @@ loser: * .tar file into the JAR linked list. * */ -static int +static int jar_listtar(JAR *jar, JAR_FILE fp) { char *s; @@ -830,37 +828,37 @@ jar_listtar(JAR *jar, JAR_FILE fp) union TarEntry tarball; while (1) { - JAR_FSEEK (fp, pos, (PRSeekWhence)0); + JAR_FSEEK(fp, pos, (PRSeekWhence)0); - if (JAR_FREAD (fp, &tarball, sizeof tarball) < sizeof tarball) - break; + if (JAR_FREAD(fp, &tarball, sizeof tarball) < sizeof tarball) + break; - if (!*tarball.val.filename) - break; + if (!*tarball.val.filename) + break; - sz = octalToLong (tarball.val.size); + sz = octalToLong(tarball.val.size); - /* Tag the end of filename */ - s = tarball.val.filename; - while (*s && *s != ' ') - s++; - *s = 0; + /* Tag the end of filename */ + s = tarball.val.filename; + while (*s && *s != ' ') + s++; + *s = 0; - /* Add to our linked list */ - phy = PORT_ZNew(JAR_Physical); - if (phy == NULL) - return JAR_ERR_MEMORY; + /* Add to our linked list */ + phy = PORT_ZNew(JAR_Physical); + if (phy == NULL) + return JAR_ERR_MEMORY; - phy->compression = 0; - phy->offset = pos + sizeof tarball; - phy->length = sz; + phy->compression = 0; + phy->offset = pos + sizeof tarball; + phy->length = sz; - ADDITEM(jar->phy, jarTypePhy, tarball.val.filename, phy, - sizeof *phy); + ADDITEM(jar->phy, jarTypePhy, tarball.val.filename, phy, + sizeof *phy); - /* Advance to next file entry */ - sz = PR_ROUNDUP(sz,sizeof tarball); - pos += sz + sizeof tarball; + /* Advance to next file entry */ + sz = PR_ROUNDUP(sz, sizeof tarball); + pos += sz + sizeof tarball; } return 0; @@ -873,13 +871,13 @@ jar_listtar(JAR *jar, JAR_FILE fp) * it will be needed. * */ -static int +static int dosdate(char *date, const char *s) { PRUint32 num = x86ShortToUint32(s); - PR_snprintf(date, 9, "%02d-%02d-%02d", ((num >> 5) & 0x0F), (num & 0x1F), - ((num >> 9) + 80)); + PR_snprintf(date, 9, "%02d-%02d-%02d", ((num >> 5) & 0x0F), (num & 0x1F), + ((num >> 9) + 80)); return 0; } @@ -890,13 +888,13 @@ dosdate(char *date, const char *s) * it will be needed. * */ -static int -dostime (char *time, const char *s) +static int +dostime(char *time, const char *s) { PRUint32 num = x86ShortToUint32(s); - PR_snprintf (time, 6, "%02d:%02d", ((num >> 11) & 0x1F), - ((num >> 5) & 0x3F)); + PR_snprintf(time, 6, "%02d:%02d", ((num >> 11) & 0x1F), + ((num >> 5) & 0x3F)); return 0; } @@ -905,7 +903,7 @@ dostime (char *time, const char *s) * Simulates an x86 (little endian, unaligned) ushort fetch from any address. */ static PRUint32 -x86ShortToUint32(const void * v) +x86ShortToUint32(const void *v) { const unsigned char *ii = (const unsigned char *)v; PRUint32 ret = (PRUint32)(ii[0]) | ((PRUint32)(ii[1]) << 8); @@ -921,10 +919,10 @@ x86LongToUint32(const void *v) const unsigned char *ll = (const unsigned char *)v; PRUint32 ret; - ret = ((((PRUint32)(ll[0])) << 0) | - (((PRUint32)(ll[1])) << 8) | - (((PRUint32)(ll[2])) << 16) | - (((PRUint32)(ll[3])) << 24)); + ret = ((((PRUint32)(ll[0])) << 0) | + (((PRUint32)(ll[1])) << 8) | + (((PRUint32)(ll[2])) << 16) | + (((PRUint32)(ll[3])) << 24)); return ret; } #endif @@ -934,16 +932,16 @@ x86LongToUint32(const void *v) * Used for integer encoding inside tar files. * */ -static long +static long octalToLong(const char *s) { long num = 0L; - while (*s == ' ') - s++; + while (*s == ' ') + s++; while (*s >= '0' && *s <= '7') { - num <<= 3; - num += *s++ - '0'; + num <<= 3; + num += *s++ - '0'; } return num; } @@ -956,13 +954,13 @@ octalToLong(const char *s) * or at its filename. * */ -static int +static int jar_guess_jar(const char *filename, JAR_FILE fp) { PRInt32 len = PORT_Strlen(filename); const char *ext = filename + len - 4; /* 4 for ".tar" */ if (len >= 4 && !PL_strcasecmp(ext, ".tar")) - return jarArchTar; + return jarArchTar; return jarArchZip; } |