Correct misunderstanding with zip64 extra records

This commit is contained in:
Justine Tunney 2023-11-18 14:35:57 -08:00
parent dbd8176ea8
commit 3e6d536822
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
9 changed files with 96 additions and 78 deletions

View file

@ -16,10 +16,10 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/errno.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/intrin/safemacros.internal.h" #include "libc/intrin/safemacros.internal.h"
#include "libc/log/internal.h" #include "libc/log/internal.h"
#include "libc/errno.h"
#include "libc/thread/thread.h" #include "libc/thread/thread.h"
/** /**
@ -30,8 +30,6 @@
relegated void __start_fatal(const char *file, int line) { relegated void __start_fatal(const char *file, int line) {
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
__restore_tty(); __restore_tty();
kprintf("%r%serror%s:%s:%d:%s%s: ", !__nocolor ? "\e[J\e[30;101m" : "", kprintf("%r%serror%s:%s:%d%s: ", !__nocolor ? "\e[J\e[30;101m" : "",
!__nocolor ? "\e[94;49m" : "", file, line, !__nocolor ? "\e[94;49m" : "", file, line, !__nocolor ? "\e[0m" : "");
firstnonnull(program_invocation_short_name, "unknown"),
!__nocolor ? "\e[0m" : "");
} }

View file

@ -21,17 +21,18 @@
/** /**
* Returns compressed size in bytes from zip central directory header. * Returns compressed size in bytes from zip central directory header.
*/ */
uint64_t GetZipCfileCompressedSize(const uint8_t *z) { int64_t GetZipCfileCompressedSize(const uint8_t *z) {
uint64_t x; if (ZIP_CFILE_COMPRESSEDSIZE(z) != 0xFFFFFFFFu) {
const uint8_t *p, *pe; return ZIP_CFILE_COMPRESSEDSIZE(z);
if ((x = ZIP_CFILE_COMPRESSEDSIZE(z)) == 0xFFFFFFFF) { }
for (p = ZIP_CFILE_EXTRA(z), pe = p + ZIP_CFILE_EXTRASIZE(z); p < pe; const uint8_t *p = ZIP_CFILE_EXTRA(z);
p += ZIP_EXTRA_SIZE(p)) { const uint8_t *pe = p + ZIP_CFILE_EXTRASIZE(z);
if (ZIP_EXTRA_HEADERID(p) == kZipExtraZip64 && for (; p < pe; p += ZIP_EXTRA_SIZE(p)) {
8 + 8 <= ZIP_EXTRA_CONTENTSIZE(p)) { if (ZIP_EXTRA_HEADERID(p) == kZipExtraZip64) {
return READ64LE(ZIP_EXTRA_CONTENT(p) + 8); if (8 <= ZIP_EXTRA_CONTENTSIZE(p)) {
return READ64LE(ZIP_EXTRA_CONTENT(p));
} }
} }
} }
return x; return -1;
} }

View file

@ -21,17 +21,25 @@
/** /**
* Returns offset of local file header. * Returns offset of local file header.
*/ */
uint64_t GetZipCfileOffset(const uint8_t *z) { int64_t GetZipCfileOffset(const uint8_t *z) {
uint64_t x; if (ZIP_CFILE_OFFSET(z) != 0xFFFFFFFFu) {
const uint8_t *p, *pe; return ZIP_CFILE_OFFSET(z);
if ((x = ZIP_CFILE_OFFSET(z)) == 0xFFFFFFFF) { }
for (p = ZIP_CFILE_EXTRA(z), pe = p + ZIP_CFILE_EXTRASIZE(z); p < pe; const uint8_t *p = ZIP_CFILE_EXTRA(z);
p += ZIP_EXTRA_SIZE(p)) { const uint8_t *pe = p + ZIP_CFILE_EXTRASIZE(z);
if (ZIP_EXTRA_HEADERID(p) == kZipExtraZip64 && for (; p < pe; p += ZIP_EXTRA_SIZE(p)) {
16 + 8 <= ZIP_EXTRA_CONTENTSIZE(p)) { if (ZIP_EXTRA_HEADERID(p) == kZipExtraZip64) {
return READ64LE(ZIP_EXTRA_CONTENT(p) + 16); int offset = 0;
if (ZIP_CFILE_COMPRESSEDSIZE(z) == 0xFFFFFFFFu) {
offset += 8;
}
if (ZIP_CFILE_UNCOMPRESSEDSIZE(z) == 0xFFFFFFFFu) {
offset += 8;
}
if (offset + 8 <= ZIP_EXTRA_CONTENTSIZE(p)) {
return READ64LE(ZIP_EXTRA_CONTENT(p) + offset);
} }
} }
} }
return x; return -1;
} }

View file

@ -21,17 +21,22 @@
/** /**
* Returns uncompressed size in bytes from zip central directory header. * Returns uncompressed size in bytes from zip central directory header.
*/ */
uint64_t GetZipCfileUncompressedSize(const uint8_t *z) { int64_t GetZipCfileUncompressedSize(const uint8_t *z) {
uint64_t x; if (ZIP_CFILE_UNCOMPRESSEDSIZE(z) != 0xFFFFFFFFu) {
const uint8_t *p, *pe; return ZIP_CFILE_UNCOMPRESSEDSIZE(z);
if ((x = ZIP_CFILE_UNCOMPRESSEDSIZE(z)) == 0xFFFFFFFF) { }
for (p = ZIP_CFILE_EXTRA(z), pe = p + ZIP_CFILE_EXTRASIZE(z); p < pe; const uint8_t *p = ZIP_CFILE_EXTRA(z);
p += ZIP_EXTRA_SIZE(p)) { const uint8_t *pe = p + ZIP_CFILE_EXTRASIZE(z);
if (ZIP_EXTRA_HEADERID(p) == kZipExtraZip64 && for (; p < pe; p += ZIP_EXTRA_SIZE(p)) {
0 + 8 <= ZIP_EXTRA_CONTENTSIZE(p)) { if (ZIP_EXTRA_HEADERID(p) == kZipExtraZip64) {
return READ64LE(ZIP_EXTRA_CONTENT(p) + 0); int offset = 0;
if (ZIP_CFILE_COMPRESSEDSIZE(z) == 0xFFFFFFFFu) {
offset += 8;
}
if (offset + 8 <= ZIP_EXTRA_CONTENTSIZE(p)) {
return READ64LE(ZIP_EXTRA_CONTENT(p) + offset);
} }
} }
} }
return x; return -1;
} }

View file

@ -21,17 +21,18 @@
/** /**
* Returns compressed size in bytes from zip local file header. * Returns compressed size in bytes from zip local file header.
*/ */
uint64_t GetZipLfileCompressedSize(const uint8_t *z) { int64_t GetZipLfileCompressedSize(const uint8_t *z) {
uint64_t x; if (ZIP_LFILE_COMPRESSEDSIZE(z) != 0xFFFFFFFFu) {
const uint8_t *p, *pe; return ZIP_LFILE_COMPRESSEDSIZE(z);
if ((x = ZIP_LFILE_COMPRESSEDSIZE(z)) == 0xFFFFFFFF) { }
for (p = ZIP_LFILE_EXTRA(z), pe = p + ZIP_LFILE_EXTRASIZE(z); p < pe; const uint8_t *p = ZIP_LFILE_EXTRA(z);
p += ZIP_EXTRA_SIZE(p)) { const uint8_t *pe = p + ZIP_LFILE_EXTRASIZE(z);
if (ZIP_EXTRA_HEADERID(p) == kZipExtraZip64 && for (; p < pe; p += ZIP_EXTRA_SIZE(p)) {
8 + 8 <= ZIP_EXTRA_CONTENTSIZE(p)) { if (ZIP_EXTRA_HEADERID(p) == kZipExtraZip64) {
return READ64LE(ZIP_EXTRA_CONTENT(p) + 8); if (8 <= ZIP_EXTRA_CONTENTSIZE(p)) {
return READ64LE(ZIP_EXTRA_CONTENT(p));
} }
} }
} }
return x; return -1;
} }

View file

@ -21,18 +21,22 @@
/** /**
* Returns uncompressed size in bytes from zip local file header. * Returns uncompressed size in bytes from zip local file header.
*/ */
uint64_t GetZipLfileUncompressedSize(const uint8_t *z) { int64_t GetZipLfileUncompressedSize(const uint8_t *z) {
uint64_t x; if (ZIP_LFILE_UNCOMPRESSEDSIZE(z) != 0xFFFFFFFFu) {
const uint8_t *p, *pe; return ZIP_LFILE_UNCOMPRESSEDSIZE(z);
x = ZIP_LFILE_UNCOMPRESSEDSIZE(z); }
if (x == 0xFFFFFFFF) { const uint8_t *p = ZIP_LFILE_EXTRA(z);
for (p = ZIP_LFILE_EXTRA(z), pe = p + ZIP_LFILE_EXTRASIZE(z); p < pe; const uint8_t *pe = p + ZIP_LFILE_EXTRASIZE(z);
p += ZIP_EXTRA_SIZE(p)) { for (; p < pe; p += ZIP_EXTRA_SIZE(p)) {
if (ZIP_EXTRA_HEADERID(p) == kZipExtraZip64 && if (ZIP_EXTRA_HEADERID(p) == kZipExtraZip64) {
0 + 8 <= ZIP_EXTRA_CONTENTSIZE(p)) { int offset = 0;
return READ64LE(ZIP_EXTRA_CONTENT(p) + 0); if (ZIP_LFILE_COMPRESSEDSIZE(z) == 0xFFFFFFFFu) {
offset += 8;
}
if (offset + 8 <= ZIP_EXTRA_CONTENTSIZE(p)) {
return READ64LE(ZIP_EXTRA_CONTENT(p) + offset);
} }
} }
} }
return x; return -1;
} }

View file

@ -102,6 +102,7 @@
#define kZipLfileHdrMagic ZM_(0x04034b50) /* PK♥♦ "PK\3\4" */ #define kZipLfileHdrMagic ZM_(0x04034b50) /* PK♥♦ "PK\3\4" */
#define kZipLfileHdrMinSize 30 #define kZipLfileHdrMinSize 30
#define kZipLfileOffsetVersionNeeded 4
#define kZipLfileOffsetGeneralflag 6 #define kZipLfileOffsetGeneralflag 6
#define kZipLfileOffsetCompressionmethod 8 #define kZipLfileOffsetCompressionmethod 8
#define kZipLfileOffsetLastmodifiedtime 10 #define kZipLfileOffsetLastmodifiedtime 10
@ -228,11 +229,11 @@ uint64_t GetZipCdirRecords(const uint8_t *);
const void *GetZipCdirComment(const uint8_t *); const void *GetZipCdirComment(const uint8_t *);
uint64_t GetZipCdirSize(const uint8_t *); uint64_t GetZipCdirSize(const uint8_t *);
uint64_t GetZipCdirCommentSize(const uint8_t *); uint64_t GetZipCdirCommentSize(const uint8_t *);
uint64_t GetZipCfileUncompressedSize(const uint8_t *); int64_t GetZipCfileCompressedSize(const uint8_t *);
uint64_t GetZipCfileCompressedSize(const uint8_t *); int64_t GetZipCfileUncompressedSize(const uint8_t *);
uint64_t GetZipCfileOffset(const uint8_t *); int64_t GetZipCfileOffset(const uint8_t *);
uint64_t GetZipLfileUncompressedSize(const uint8_t *); int64_t GetZipLfileCompressedSize(const uint8_t *);
uint64_t GetZipLfileCompressedSize(const uint8_t *); int64_t GetZipLfileUncompressedSize(const uint8_t *);
void GetZipCfileTimestamps(const uint8_t *, struct timespec *, void GetZipCfileTimestamps(const uint8_t *, struct timespec *,
struct timespec *, struct timespec *, int); struct timespec *, struct timespec *, int);

View file

@ -676,7 +676,7 @@ static void LoadSymbols(Elf64_Ehdr *e, Elf64_Off size, const char *path) {
WRITE32LE(cfile, kZipCfileHdrMagic); WRITE32LE(cfile, kZipCfileHdrMagic);
cfile[4] = kZipCosmopolitanVersion; cfile[4] = kZipCosmopolitanVersion;
cfile[5] = kZipOsUnix; cfile[5] = kZipOsUnix;
cfile[6] = kZipEra1993; cfile[6] = kZipEra2001;
WRITE16LE(cfile + kZipCfileOffsetCompressionmethod, kZipCompressionDeflate); WRITE16LE(cfile + kZipCfileOffsetCompressionmethod, kZipCompressionDeflate);
WRITE16LE(cfile + kZipCfileOffsetLastmodifieddate, DOS_DATE(2023, 7, 29)); WRITE16LE(cfile + kZipCfileOffsetLastmodifieddate, DOS_DATE(2023, 7, 29));
WRITE16LE(cfile + kZipCfileOffsetLastmodifiedtime, DOS_TIME(0, 0, 0)); WRITE16LE(cfile + kZipCfileOffsetLastmodifiedtime, DOS_TIME(0, 0, 0));
@ -690,8 +690,8 @@ static void LoadSymbols(Elf64_Ehdr *e, Elf64_Off size, const char *path) {
unsigned char *lfile = Malloc(lfile_size); unsigned char *lfile = Malloc(lfile_size);
bzero(lfile, lfile_size); bzero(lfile, lfile_size);
WRITE32LE(lfile, kZipLfileHdrMagic); WRITE32LE(lfile, kZipLfileHdrMagic);
cfile[4] = kZipEra1993; WRITE16LE(lfile + kZipLfileOffsetVersionNeeded, kZipEra2001);
cfile[5] = kZipOsDos; WRITE16LE(lfile + kZipLfileOffsetGeneralflag, kZipGflagUtf8);
WRITE16LE(lfile + kZipLfileOffsetCompressionmethod, kZipCompressionDeflate); WRITE16LE(lfile + kZipLfileOffsetCompressionmethod, kZipCompressionDeflate);
WRITE16LE(lfile + kZipLfileOffsetLastmodifieddate, DOS_DATE(2023, 7, 29)); WRITE16LE(lfile + kZipLfileOffsetLastmodifieddate, DOS_DATE(2023, 7, 29));
WRITE16LE(lfile + kZipLfileOffsetLastmodifiedtime, DOS_TIME(0, 0, 0)); WRITE16LE(lfile + kZipLfileOffsetLastmodifiedtime, DOS_TIME(0, 0, 0));

View file

@ -3695,8 +3695,8 @@ static void StoreAsset(const char *path, size_t pathlen, const char *data,
p = WRITE16LE(p, mtime); p = WRITE16LE(p, mtime);
p = WRITE16LE(p, mdate); p = WRITE16LE(p, mdate);
p = WRITE32LE(p, crc); p = WRITE32LE(p, crc);
p = WRITE32LE(p, MIN(uselen, 0xffffffff)); p = WRITE32LE(p, 0xffffffffu);
p = WRITE32LE(p, MIN(datalen, 0xffffffff)); p = WRITE32LE(p, 0xffffffffu);
p = WRITE16LE(p, pathlen); p = WRITE16LE(p, pathlen);
p = WRITE16LE(p, v[2].iov_len); p = WRITE16LE(p, v[2].iov_len);
v[1].iov_len = pathlen; v[1].iov_len = pathlen;
@ -3755,8 +3755,8 @@ static void StoreAsset(const char *path, size_t pathlen, const char *data,
p = WRITE16LE(p, mtime); p = WRITE16LE(p, mtime);
p = WRITE16LE(p, mdate); p = WRITE16LE(p, mdate);
p = WRITE32LE(p, crc); p = WRITE32LE(p, crc);
p = WRITE32LE(p, MIN(uselen, 0xffffffff)); p = WRITE32LE(p, 0xffffffffu);
p = WRITE32LE(p, MIN(datalen, 0xffffffff)); p = WRITE32LE(p, 0xffffffffu);
p = WRITE16LE(p, pathlen); p = WRITE16LE(p, pathlen);
p = WRITE16LE(p, v[8].iov_len + v[9].iov_len); p = WRITE16LE(p, v[8].iov_len + v[9].iov_len);
p = WRITE16LE(p, 0); p = WRITE16LE(p, 0);
@ -3764,7 +3764,7 @@ static void StoreAsset(const char *path, size_t pathlen, const char *data,
p = WRITE16LE(p, iattrs); p = WRITE16LE(p, iattrs);
p = WRITE16LE(p, dosmode); p = WRITE16LE(p, dosmode);
p = WRITE16LE(p, mode); p = WRITE16LE(p, mode);
p = WRITE32LE(p, MIN(zsize, 0xffffffff)); p = WRITE32LE(p, 0xffffffffu);
v[7].iov_len = pathlen; v[7].iov_len = pathlen;
v[7].iov_base = (void *)path; v[7].iov_base = (void *)path;
// zip64 end of central directory // zip64 end of central directory