diff --git a/libc/intrin/ftrapv.c b/libc/intrin/ftrapv.c index 75719f5e3..3cf108e4c 100644 --- a/libc/intrin/ftrapv.c +++ b/libc/intrin/ftrapv.c @@ -39,8 +39,8 @@ int __negvsi2(int x) { * @see __on_arithmetic_overflow() * @see -ftrapv to enable */ -long __negvdi2(long x) { - if (x == LONG_MIN) { +long long __negvdi2(long long x) { + if (x == LLONG_MIN) { __on_arithmetic_overflow(); } return -x; @@ -79,8 +79,8 @@ int __addvsi3(int x, int y) { * @see __on_arithmetic_overflow() * @see -ftrapv to enable */ -long __addvdi3(long x, long y) { - long z; +long long __addvdi3(long long x, long long y) { + long long z; if (ckd_add(&z, x, y)) { __on_arithmetic_overflow(); } @@ -121,8 +121,8 @@ int __subvsi3(int x, int y) { * @see __on_arithmetic_overflow() * @see -ftrapv to enable */ -long __subvdi3(long x, long y) { - long z; +long long __subvdi3(long long x, long long y) { + long long z; if (ckd_sub(&z, x, y)) { __on_arithmetic_overflow(); } @@ -163,22 +163,8 @@ int __mulvsi3(int x, int y) { * @see __on_arithmetic_overflow() * @see -ftrapv to enable */ -long __mulvdi3(long x, long y) { - long z; - if (ckd_mul(&z, x, y)) { - __on_arithmetic_overflow(); - } - return z; -} - -/** - * Returns 𝑥*𝑦, aborting on overflow. - * - * @see __on_arithmetic_overflow() - * @see -ftrapv to enable - */ -int128_t __mulvti3(int128_t x, int128_t y) { - int128_t z; +long long __mulvdi3(long long x, long long y) { + long long z; if (ckd_mul(&z, x, y)) { __on_arithmetic_overflow(); } diff --git a/libc/str/findembeddedape.c b/libc/intrin/mulvti3.c similarity index 63% rename from libc/str/findembeddedape.c rename to libc/intrin/mulvti3.c index f522d98a2..b0c049b85 100644 --- a/libc/str/findembeddedape.c +++ b/libc/intrin/mulvti3.c @@ -1,7 +1,7 @@ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2021 Justine Alexandra Roberts Tunney │ +│ Copyright 2023 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ @@ -16,35 +16,20 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/intrin/bits.h" -#include "libc/log/libfatal.internal.h" -#include "libc/macros.internal.h" -#include "libc/str/str.h" +#include "libc/runtime/internal.h" -#define TRIES 8 +int128_t __muloti4(int128_t, int128_t, int *); /** - * Returns offset of binary embedded inside binary. + * Returns 𝑥*𝑦, aborting on overflow. * - * This can be used to load zip assets from an executable that hasn't - * gone through the `objcopy -S -O binary` step. We make the assumption - * that an x86_64-pc-linux-gnu toolchain is being used. This routine - * would need to be changed to accommodate binaries built locally on - * Apple, FreeBSD, etc. - * - * @param p needs to be page aligned - * @param n is byte length of p - * @return base address of image or NULL if not found + * @see __on_arithmetic_overflow() + * @see -ftrapv to enable */ -uint8_t *FindEmbeddedApe(const uint8_t *p, size_t n) { - size_t i; - uint64_t w; - n = MIN(n, TRIES * PAGESIZE); - for (i = 0; i + 8 <= n; i += PAGESIZE) { - w = READ64LE(p + i); - if (w == READ64LE("MZqFpD='") || w == READ64LE("\177ELF\2\1\1\11")) { - return (/*unconst*/ uint8_t *)(p + i); - } - } - return 0; +int128_t __mulvti3(int128_t x, int128_t y) { + int o; + int128_t z; + z = __muloti4(x, y, &o); + if (o) __on_arithmetic_overflow(); + return z; } diff --git a/libc/str/iszipeocd32.c b/libc/str/iszipeocd32.c index ceb9d906a..30925daad 100644 --- a/libc/str/iszipeocd32.c +++ b/libc/str/iszipeocd32.c @@ -16,12 +16,14 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdckdint.h" #include "libc/zip.internal.h" /** * Determines if ZIP EOCD record seems legit. */ int IsZipEocd32(const uint8_t *p, size_t n, size_t i) { + size_t offset; if (i > n || n - i < kZipCdirHdrMinSize) { return kZipErrorEocdOffsetOverflow; } @@ -35,12 +37,15 @@ int IsZipEocd32(const uint8_t *p, size_t n, size_t i) { return kZipErrorEocdDiskMismatch; } if (ZIP_CDIR_RECORDSONDISK(p + i) != ZIP_CDIR_RECORDS(p + i)) { - return kZipErrorCdirRecordsMismatch; + return kZipErrorEocdRecordsMismatch; } if (ZIP_CDIR_RECORDS(p + i) * kZipCfileHdrMinSize > ZIP_CDIR_SIZE(p + i)) { - return kZipErrorCdirRecordsOverflow; + return kZipErrorEocdRecordsOverflow; } - if (ZIP_CDIR_OFFSET(p + i) + ZIP_CDIR_SIZE(p + i) > i) { + if (ckd_add(&offset, ZIP_CDIR_OFFSET(p + i), ZIP_CDIR_SIZE(p + i))) { + return kZipErrorEocdOffsetSizeOverflow; + } + if (offset > i) { return kZipErrorCdirOffsetPastEocd; } return kZipOk; diff --git a/libc/str/iszipeocd64.c b/libc/str/iszipeocd64.c index 5619381f1..b5415a39c 100644 --- a/libc/str/iszipeocd64.c +++ b/libc/str/iszipeocd64.c @@ -16,34 +16,41 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/stdckdint.h" #include "libc/zip.internal.h" /** * Returns kZipOk if zip64 end of central directory header seems legit. */ int IsZipEocd64(const uint8_t *p, size_t n, size_t i) { - if (i + kZipCdir64HdrMinSize > n) { + size_t off, loc; + uint64_t cdsize; + if (i > n || i + kZipCdir64HdrMinSize > n) { return kZipErrorEocdOffsetOverflow; } if (READ32LE(p + i) != kZipCdir64HdrMagic) { return kZipErrorEocdMagicNotFound; } - if (i + ZIP_CDIR64_HDRSIZE(p + i) + kZipCdir64LocatorSize > n) { + if (ckd_add(&loc, i, ZIP_CDIR64_HDRSIZE(p + i)) || // + ckd_add(&off, loc, kZipCdir64LocatorSize) || // + off > n) { // return kZipErrorEocdSizeOverflow; } - if (ZIP_LOCATE64_MAGIC(p + i + ZIP_CDIR64_HDRSIZE(p + i)) != - kZipCdir64LocatorMagic) { - return kZipErrorCdirLocatorMagic; + if (ZIP_LOCATE64_MAGIC(p + loc) != kZipCdir64LocatorMagic) { + return kZipErrorEocdLocatorMagic; } - if (ZIP_LOCATE64_OFFSET(p + i + ZIP_CDIR64_HDRSIZE(p + i)) != i) { - return kZipErrorCdirLocatorOffset; + if (ZIP_LOCATE64_OFFSET(p + loc) != i) { + return kZipErrorEocdLocatorOffset; } - if (ZIP_CDIR64_RECORDS(p + i) * kZipCfileHdrMinSize > - ZIP_CDIR64_SIZE(p + i)) { - return kZipErrorCdirRecordsOverflow; + if (ckd_add(&off, ZIP_CDIR64_OFFSET(p + i), ZIP_CDIR64_SIZE(p + i))) { + return kZipErrorEocdOffsetSizeOverflow; } - if (ZIP_CDIR64_OFFSET(p + i) + ZIP_CDIR64_SIZE(p + i) > i) { + if (off > i) { return kZipErrorCdirOffsetPastEocd; } + if (ckd_mul(&cdsize, ZIP_CDIR64_RECORDS(p + i), kZipCfileHdrMinSize) || + cdsize > ZIP_CDIR64_SIZE(p + i)) { + return kZipErrorEocdRecordsOverflow; + } return kZipOk; } diff --git a/libc/zip.internal.h b/libc/zip.internal.h index 9d2c3558c..a784ff9c2 100644 --- a/libc/zip.internal.h +++ b/libc/zip.internal.h @@ -15,20 +15,27 @@ #define ZM_(x) ~VEIL("r", ~x) /* prevent magic from appearing in binary */ #endif -#define kZipOk 0 -#define kZipErrorEocdNotFound -1 -#define kZipErrorEocdOffsetOverflow -2 -#define kZipErrorEocdMagicNotFound -3 -#define kZipErrorEocdSizeOverflow -4 -#define kZipErrorEocdDiskMismatch -5 -#define kZipErrorCdirRecordsMismatch -6 -#define kZipErrorCdirRecordsOverflow -7 -#define kZipErrorCdirOffsetPastEocd -8 -#define kZipErrorCdirLocatorMagic -9 -#define kZipErrorCdirLocatorOffset -10 -#define kZipErrorRaceCondition -11 -#define kZipErrorMapFailed -12 -#define kZipErrorOpenFailed -13 +#ifdef TINY +#define _ZE(x) -1 +#else +#define _ZE(x) x +#endif + +#define kZipOk 0 +#define kZipErrorEocdNotFound _ZE(-1) +#define kZipErrorEocdOffsetOverflow _ZE(-2) +#define kZipErrorEocdMagicNotFound _ZE(-3) +#define kZipErrorEocdSizeOverflow _ZE(-4) +#define kZipErrorEocdDiskMismatch _ZE(-5) +#define kZipErrorEocdOffsetSizeOverflow _ZE(-6) +#define kZipErrorEocdRecordsMismatch _ZE(-7) +#define kZipErrorEocdRecordsOverflow _ZE(-8) +#define kZipErrorCdirOffsetPastEocd _ZE(-9) +#define kZipErrorEocdLocatorMagic _ZE(-10) +#define kZipErrorEocdLocatorOffset _ZE(-11) +#define kZipErrorRaceCondition _ZE(-12) +#define kZipErrorMapFailed _ZE(-13) +#define kZipErrorOpenFailed _ZE(-14) #define kZipCosmopolitanVersion kZipEra2001 @@ -75,7 +82,7 @@ #define kZipCdirOffsetOffset 16 #define kZipCdirCommentSizeOffset 20 -#define kZipCdir64HdrMagic ZM_(0x06064b50) /* PK♣♠ "PK\6\6" */ +#define kZipCdir64HdrMagic ZM_(0x06064b50) /* PK♠♠ "PK\6\6" */ #define kZipCdir64HdrMinSize 56 #define kZipCdir64LocatorMagic ZM_(0x07064b50) /* PK♠• "PK\6\7" */ #define kZipCdir64LocatorSize 20 @@ -211,7 +218,6 @@ #define ZIP_EXTRA_SIZE(P) (ZIP_EXTRA_CONTENTSIZE(P) + kZipExtraHdrSize) void *GetZipEocd(const void *, size_t, int *); -uint8_t *FindEmbeddedApe(const uint8_t *, size_t); int IsZipEocd32(const uint8_t *, size_t, size_t); int IsZipEocd64(const uint8_t *, size_t, size_t); int GetZipCfileMode(const uint8_t *); diff --git a/libc/zipos/get.c b/libc/zipos/get.c index f2718997c..e3242bd31 100644 --- a/libc/zipos/get.c +++ b/libc/zipos/get.c @@ -67,9 +67,9 @@ struct Zipos *__zipos_get(void) { int fd, err, msg; static bool once; struct Zipos *res; + uint8_t *map, *cdir; const char *progpath; static struct Zipos zipos; - uint8_t *map, *base, *cdir; __zipos_lock(); if (!once) { progpath = getenv("COSMOPOLITAN_INIT_ZIPOS"); @@ -86,15 +86,11 @@ struct Zipos *__zipos_get(void) { } if (fd != -1) { if ((size = lseek(fd, 0, SEEK_END)) != -1 && - (map = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0)) != MAP_FAILED) { - if ((base = FindEmbeddedApe(map, size))) { - size -= base - map; - } else { - base = map; - } - if ((cdir = GetZipEocd(base, size, &err)) && - _cmpxchg(&zipos.map, 0, base)) { - __zipos_munmap_unneeded(base, cdir, map); + (map = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0)) != + MAP_FAILED) { + if ((cdir = GetZipEocd(map, size, &err))) { + __zipos_munmap_unneeded(map, cdir, map); + zipos.map = map; zipos.cdir = cdir; msg = kZipOk; } else { diff --git a/tool/build/zipbase.c b/tool/build/zipbase.c deleted file mode 100644 index a7d63d82a..000000000 --- a/tool/build/zipbase.c +++ /dev/null @@ -1,78 +0,0 @@ -#if 0 -/*─────────────────────────────────────────────────────────────────╗ -│ To the extent possible under law, Justine Tunney has waived │ -│ all copyright and related or neighboring rights to this file, │ -│ as it is written in the following disclaimers: │ -│ • http://unlicense.org/ │ -│ • http://creativecommons.org/publicdomain/zero/1.0/ │ -╚─────────────────────────────────────────────────────────────────*/ -#endif -#include "libc/calls/calls.h" -#include "libc/calls/struct/stat.h" -#include "libc/log/check.h" -#include "libc/macros.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/o.h" -#include "libc/sysv/consts/prot.h" -#include "libc/zip.internal.h" - -int main(int argc, char *argv[]) { - - if (argc != 2) { - fprintf(stderr, "usage: %s FOO.COM\n", argv[0]); - fprintf(stderr, - "prints lowest file offset (in decimal bytes) at which zip\n" - "records exist within a .com, .com.dbg, or .zip file\n"); - exit(1); - } - - int fd = open(argv[1], O_RDONLY); - if (fd == -1) { - perror(argv[1]); - exit(1); - } - - size_t n; - struct stat st; - CHECK_EQ(0, fstat(fd, &st)); - n = st.st_size; - - uint8_t *m; - CHECK_NE(MAP_FAILED, (m = mmap(0, n, PROT_READ, MAP_PRIVATE, fd, 0))); - - int err; - uint8_t *b, *d, *p; - if ((p = FindEmbeddedApe(m, n))) { - b = p; - n -= p - m; - } else { - b = m; - } - if (!(d = GetZipEocd(b, n, &err))) { - fprintf(stderr, "%s: couldn't locate central directory [zip error %d]\n", - argv[1], err); - exit(1); - } - - size_t zsize = n; - uint8_t *zmap = m; - uint8_t *zbase = b; - uint8_t *zcdir = d; - DCHECK(IsZipEocd32(zbase, zsize, zcdir - zbase) == kZipOk || - IsZipEocd64(zbase, zsize, zcdir - zbase) == kZipOk); - - uint64_t cf; - uint64_t lf; - uint64_t minzipoffset; - n = GetZipCdirRecords(zcdir); - minzipoffset = cf = GetZipCdirOffset(zcdir); - for (; n--; cf += ZIP_CFILE_HDRSIZE(zbase + cf)) { - CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zbase + cf)); - lf = GetZipCfileOffset(zbase + cf); - minzipoffset = MIN(minzipoffset, lf); - } - - printf("%ld\n", (zbase + minzipoffset) - m); -} diff --git a/tool/build/zipcopy.c b/tool/build/zipcopy.c index 0d416e883..f3fbf815d 100644 --- a/tool/build/zipcopy.c +++ b/tool/build/zipcopy.c @@ -123,12 +123,15 @@ static void CopyZip(void) { unsigned char *ineof, *stop, *eocd, *cdir, *lfile, *cfile; // find zip eocd header - ineof = (unsigned char *)inmap + insize; + ineof = inmap + insize; eocd = ineof - kZipCdirHdrMinSize; stop = MAX(eocd - 65536, inmap); for (;; --eocd) { if (eocd < stop) return; if (READ32LE(eocd) == kZipCdirHdrMagic) { + if (IsZipEocd32(inmap, insize, eocd - inmap) != kZipOk) { + Die(inpath, "found bad eocd record"); + } break; } } diff --git a/tool/decode/zip.c b/tool/decode/zip.c index 3ead0b531..8b66bf48d 100644 --- a/tool/decode/zip.c +++ b/tool/decode/zip.c @@ -430,10 +430,6 @@ void DisassembleZip(const char *path, uint8_t *p, size_t n) { uint16_t i; static int records; uint8_t *eocd32, *eocd64, *cdir, *cf, *lf, *q; - if (_endswith(path, ".com.dbg") && (q = memmem(p, n, "MZqFpD", 6))) { - n -= q - p; - p += q - p; - } eocd32 = GetZipCdir32(p, n); eocd64 = GetZipCdir64(p, n); CHECK(eocd32 || eocd64); diff --git a/tool/net/redbean.c b/tool/net/redbean.c index 0893ef426..7f5e19d5d 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -482,7 +482,6 @@ static size_t zsize; static lua_State *GL; static lua_State *YL; static uint8_t *zmap; -static uint8_t *zbase; static uint8_t *zcdir; static size_t hdrsize; static size_t amtread; @@ -2089,11 +2088,11 @@ static int64_t GetGmtOffset(int64_t t) { forceinline bool IsCompressed(struct Asset *a) { return !a->file && - ZIP_LFILE_COMPRESSIONMETHOD(zbase + a->lf) == kZipCompressionDeflate; + ZIP_LFILE_COMPRESSIONMETHOD(zmap + a->lf) == kZipCompressionDeflate; } forceinline int GetMode(struct Asset *a) { - return a->file ? a->file->st.st_mode : GetZipCfileMode(zbase + a->cf); + return a->file ? a->file->st.st_mode : GetZipCfileMode(zmap + a->cf); } forceinline bool IsCompressionMethodSupported(int method) { @@ -2140,26 +2139,25 @@ static void IndexAssets(void) { n = GetZipCdirRecords(zcdir); m = _roundup2pow(MAX(1, n) * HASH_LOAD_FACTOR); p = xcalloc(m, sizeof(struct Asset)); - for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zbase + cf)) { - CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zbase + cf)); - if (!IsCompressionMethodSupported( - ZIP_CFILE_COMPRESSIONMETHOD(zbase + cf))) { + for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) { + CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf)); + if (!IsCompressionMethodSupported(ZIP_CFILE_COMPRESSIONMETHOD(zmap + cf))) { WARNF("(zip) don't understand zip compression method %d used by %`'.*s", - ZIP_CFILE_COMPRESSIONMETHOD(zbase + cf), - ZIP_CFILE_NAMESIZE(zbase + cf), ZIP_CFILE_NAME(zbase + cf)); + ZIP_CFILE_COMPRESSIONMETHOD(zmap + cf), + ZIP_CFILE_NAMESIZE(zmap + cf), ZIP_CFILE_NAME(zmap + cf)); continue; } - hash = Hash(ZIP_CFILE_NAME(zbase + cf), ZIP_CFILE_NAMESIZE(zbase + cf)); + hash = Hash(ZIP_CFILE_NAME(zmap + cf), ZIP_CFILE_NAMESIZE(zmap + cf)); step = 0; do { i = (hash + (step * (step + 1)) >> 1) & (m - 1); ++step; } while (p[i].hash); - GetZipCfileTimestamps(zbase + cf, &lm, 0, 0, gmtoff); + GetZipCfileTimestamps(zmap + cf, &lm, 0, 0, gmtoff); p[i].hash = hash; p[i].cf = cf; - p[i].lf = GetZipCfileOffset(zbase + cf); - p[i].istext = !!(ZIP_CFILE_INTERNALATTRIBUTES(zbase + cf) & kZipIattrText); + p[i].lf = GetZipCfileOffset(zmap + cf); + p[i].istext = !!(ZIP_CFILE_INTERNALATTRIBUTES(zmap + cf) & kZipIattrText); p[i].lastmodified = lm.tv_sec; p[i].lastmodifiedstr = FormatUnixHttpDateTime(xmalloc(30), lm.tv_sec); } @@ -2171,7 +2169,7 @@ static bool OpenZip(bool force) { int fd; size_t n; struct stat st; - uint8_t *m, *b, *d, *p; + uint8_t *m, *d, *p; if (stat(zpath, &st) != -1) { if (force || st.st_ino != zst.st_ino || st.st_size > zst.st_size) { if (st.st_ino == zst.st_ino) { @@ -2183,22 +2181,15 @@ static bool OpenZip(bool force) { if ((m = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) != MAP_FAILED) { n = st.st_size; - if ((p = FindEmbeddedApe(m, n))) { - b = p; - n -= p - m; - } else { - b = m; - } - if ((d = GetZipEocd(b, n, 0))) { + if ((d = GetZipEocd(m, n, 0))) { if (zmap) { - LOGIFNEG1(munmap(zmap, zbase + zsize - zmap)); + LOGIFNEG1(munmap(zmap, zsize)); } zmap = m; - zbase = b; zsize = n; zcdir = d; - DCHECK(IsZipEocd32(zbase, zsize, zcdir - zbase) == kZipOk || - IsZipEocd64(zbase, zsize, zcdir - zbase) == kZipOk); + DCHECK(IsZipEocd32(zmap, zsize, zcdir - zmap) == kZipOk || + IsZipEocd64(zmap, zsize, zcdir - zmap) == kZipOk); memcpy(&zst, &st, sizeof(st)); IndexAssets(); return true; @@ -2228,8 +2219,8 @@ static struct Asset *GetAssetZip(const char *path, size_t pathlen) { i = (hash + (step * (step + 1)) >> 1) & (assets.n - 1); if (!assets.p[i].hash) return NULL; if (hash == assets.p[i].hash && - pathlen == ZIP_CFILE_NAMESIZE(zbase + assets.p[i].cf) && - memcmp(path, ZIP_CFILE_NAME(zbase + assets.p[i].cf), pathlen) == 0) { + pathlen == ZIP_CFILE_NAMESIZE(zmap + assets.p[i].cf) && + memcmp(path, ZIP_CFILE_NAME(zmap + assets.p[i].cf), pathlen) == 0) { return &assets.p[i]; } } @@ -2378,18 +2369,18 @@ static void *LoadAsset(struct Asset *a, size_t *out_size) { return NULL; } if (!a->file) { - size = GetZipLfileUncompressedSize(zbase + a->lf); + size = GetZipLfileUncompressedSize(zmap + a->lf); if (size == SIZE_MAX || !(data = malloc(size + 1))) return NULL; if (IsCompressed(a)) { - if (!Inflate(data, size, ZIP_LFILE_CONTENT(zbase + a->lf), - GetZipCfileCompressedSize(zbase + a->cf))) { + if (!Inflate(data, size, ZIP_LFILE_CONTENT(zmap + a->lf), + GetZipCfileCompressedSize(zmap + a->cf))) { free(data); return NULL; } } else { - memcpy(data, ZIP_LFILE_CONTENT(zbase + a->lf), size); + memcpy(data, ZIP_LFILE_CONTENT(zmap + a->lf), size); } - if (!Verify(data, size, ZIP_LFILE_CRC32(zbase + a->lf))) { + if (!Verify(data, size, ZIP_LFILE_CRC32(zmap + a->lf))) { free(data); return NULL; } @@ -2536,10 +2527,10 @@ static char *ServeErrorImpl(unsigned code, const char *reason, cpm.content = FreeLater(xslurp(a->file->path.s, &cpm.contentlength)); return AppendContentType(p, "text/html; charset=utf-8"); } else { - cpm.content = (char *)ZIP_LFILE_CONTENT(zbase + a->lf); - cpm.contentlength = GetZipCfileCompressedSize(zbase + a->cf); + cpm.content = (char *)ZIP_LFILE_CONTENT(zmap + a->lf); + cpm.contentlength = GetZipCfileCompressedSize(zmap + a->cf); if (IsCompressed(a)) { - n = GetZipLfileUncompressedSize(zbase + a->lf); + n = GetZipLfileUncompressedSize(zmap + a->lf); if ((s = FreeLater(malloc(n))) && Inflate(s, n, cpm.content, cpm.contentlength)) { cpm.content = s; @@ -2548,8 +2539,7 @@ static char *ServeErrorImpl(unsigned code, const char *reason, return ServeDefaultErrorPage(p, code, reason, details); } } - if (Verify(cpm.content, cpm.contentlength, - ZIP_LFILE_CRC32(zbase + a->lf))) { + if (Verify(cpm.content, cpm.contentlength, ZIP_LFILE_CRC32(zmap + a->lf))) { return AppendContentType(p, "text/html; charset=utf-8"); } else { return ServeDefaultErrorPage(p, code, reason, details); @@ -2747,7 +2737,7 @@ static ssize_t InflateGenerator(struct iovec v[3]) { dg.t = dg.s.avail_out ? 1 : 2; } else if (rc == Z_STREAM_END) { CHECK_EQ(Z_OK, inflateEnd(&dg.s)); - CHECK_EQ(ZIP_CFILE_CRC32(zbase + dg.a->cf), dg.c); + CHECK_EQ(ZIP_CFILE_CRC32(zmap + dg.a->cf), dg.c); dg.t = 3; } return v[0].iov_len + v[1].iov_len + v[2].iov_len; @@ -2759,7 +2749,7 @@ static char *ServeAssetDecompressed(struct Asset *a) { uint32_t crc; LockInc(&shared->c.inflates); LockInc(&shared->c.decompressedresponses); - size = GetZipCfileUncompressedSize(zbase + a->cf); + size = GetZipCfileUncompressedSize(zmap + a->cf); DEBUGF("(srvr) ServeAssetDecompressed(%ld)→%ld", cpm.contentlength, size); if (cpm.msg.method == kHttpHead) { cpm.content = 0; @@ -2777,7 +2767,7 @@ static char *ServeAssetDecompressed(struct Asset *a) { return SetStatus(200, "OK"); } else if ((p = FreeLater(malloc(size))) && Inflate(p, size, cpm.content, cpm.contentlength) && - Verify(p, size, ZIP_CFILE_CRC32(zbase + a->cf))) { + Verify(p, size, ZIP_CFILE_CRC32(zmap + a->cf))) { cpm.content = p; cpm.contentlength = size; return SetStatus(200, "OK"); @@ -2797,8 +2787,8 @@ static inline char *ServeAssetPrecompressed(struct Asset *a) { uint32_t crc; DEBUGF("(srvr) ServeAssetPrecompressed()"); LockInc(&shared->c.precompressedresponses); - crc = ZIP_CFILE_CRC32(zbase + a->cf); - size = GetZipCfileUncompressedSize(zbase + a->cf); + crc = ZIP_CFILE_CRC32(zmap + a->cf); + size = GetZipCfileUncompressedSize(zmap + a->cf); cpm.gzipped = size; WRITE32LE(gzip_footer + 0, crc); WRITE32LE(gzip_footer + 4, size); @@ -3005,7 +2995,7 @@ td { padding-right: 3em; }\r\n\ GetZipCdirComment(zcdir)); bzero(w, sizeof(w)); n = GetZipCdirRecords(zcdir); - for (zcf = zbase + GetZipCdirOffset(zcdir); n--; + for (zcf = zmap + GetZipCdirOffset(zcdir); n--; zcf += ZIP_CFILE_HDRSIZE(zcf)) { CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zcf)); path = GetAssetPath(zcf, &pathlen); @@ -3017,7 +3007,7 @@ td { padding-right: 3em; }\r\n\ free(path); } n = GetZipCdirRecords(zcdir); - for (zcf = zbase + GetZipCdirOffset(zcdir); n--; + for (zcf = zmap + GetZipCdirOffset(zcdir); n--; zcf += ZIP_CFILE_HDRSIZE(zcf)) { CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zcf)); path = GetAssetPath(zcf, &pathlen); @@ -3590,9 +3580,9 @@ static int LuaLoadAsset(lua_State *L) { if ((a = GetAsset(path, pathlen))) { if (!a->file && !IsCompressed(a)) { /* fast path: this avoids extra copy */ - data = ZIP_LFILE_CONTENT(zbase + a->lf); - size = GetZipLfileUncompressedSize(zbase + a->lf); - if (Verify(data, size, ZIP_LFILE_CRC32(zbase + a->lf))) { + data = ZIP_LFILE_CONTENT(zmap + a->lf); + size = GetZipLfileUncompressedSize(zmap + a->lf); + if (Verify(data, size, ZIP_LFILE_CRC32(zmap + a->lf))) { lua_pushlstring(L, data, size); return 1; } @@ -3711,15 +3701,15 @@ static void StoreAsset(char *path, size_t pathlen, char *data, size_t datalen, if (a) { // to remove an existing asset, // first copy the central directory part before its record - v[4].iov_base = zbase + oldcdiroffset; + v[4].iov_base = zmap + oldcdiroffset; v[4].iov_len = a->cf - oldcdiroffset; // and then the rest of the central directory - v[5].iov_base = zbase + oldcdiroffset + - (v[4].iov_len + ZIP_CFILE_HDRSIZE(zbase + a->cf)); + v[5].iov_base = + zmap + oldcdiroffset + (v[4].iov_len + ZIP_CFILE_HDRSIZE(zmap + a->cf)); v[5].iov_len = - oldcdirsize - (v[4].iov_len + ZIP_CFILE_HDRSIZE(zbase + a->cf)); + oldcdirsize - (v[4].iov_len + ZIP_CFILE_HDRSIZE(zmap + a->cf)); } else { - v[4].iov_base = zbase + oldcdiroffset; + v[4].iov_base = zmap + oldcdiroffset; v[4].iov_len = oldcdirsize; v[5].iov_base = 0; v[5].iov_len = 0; @@ -3807,7 +3797,7 @@ static void StoreAsset(char *path, size_t pathlen, char *data, size_t datalen, p = WRITE32LE(p, MIN(cdirsize, 0xffffffff)); p = WRITE32LE(p, MIN(cdiroffset, 0xffffffff)); p = WRITE16LE(p, v[12].iov_len); - CHECK_NE(-1, lseek(zfd, zbase + zsize - zmap, SEEK_SET)); + CHECK_NE(-1, lseek(zfd, zmap + zsize - zmap, SEEK_SET)); CHECK_NE(-1, WritevAll(zfd, v, 13)); CHECK_NE(-1, fcntl(zfd, F_SETLK, &(struct flock){F_UNLCK})); ////////////////////////////////////////////////////////////////////////////// @@ -4718,7 +4708,7 @@ static int LuaGetZipPaths(lua_State *L) { lua_newtable(L); i = 0; n = GetZipCdirRecords(zcdir); - for (zcf = zbase + GetZipCdirOffset(zcdir); n--; + for (zcf = zmap + GetZipCdirOffset(zcdir); n--; zcf += ZIP_CFILE_HDRSIZE(zcf)) { CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zcf)); path = GetAssetPath(zcf, &pathlen); @@ -4755,7 +4745,7 @@ static int LuaGetAssetLastModifiedTime(lua_State *L) { if (a->file) { zuluseconds = a->file->st.st_mtim.tv_sec; } else { - GetZipCfileTimestamps(zbase + a->cf, &lm, 0, 0, gmtoff); + GetZipCfileTimestamps(zmap + a->cf, &lm, 0, 0, gmtoff); zuluseconds = lm.tv_sec; } lua_pushinteger(L, zuluseconds); @@ -4774,7 +4764,7 @@ static int LuaGetAssetSize(lua_State *L) { if (a->file) { lua_pushinteger(L, a->file->st.st_size); } else { - lua_pushinteger(L, GetZipLfileUncompressedSize(zbase + a->lf)); + lua_pushinteger(L, GetZipLfileUncompressedSize(zmap + a->lf)); } } else { lua_pushnil(L); @@ -5004,9 +4994,9 @@ static int LuaGetAssetComment(lua_State *L) { size_t pathlen, m; path = LuaCheckPath(L, 1, &pathlen); if ((a = GetAssetZip(path, pathlen)) && - (m = strnlen(ZIP_CFILE_COMMENT(zbase + a->cf), - ZIP_CFILE_COMMENTSIZE(zbase + a->cf)))) { - lua_pushlstring(L, ZIP_CFILE_COMMENT(zbase + a->cf), m); + (m = strnlen(ZIP_CFILE_COMMENT(zmap + a->cf), + ZIP_CFILE_COMMENTSIZE(zmap + a->cf)))) { + lua_pushlstring(L, ZIP_CFILE_COMMENT(zmap + a->cf), m); } else { lua_pushnil(L); } @@ -6094,8 +6084,8 @@ static inline bool IsLua(struct Asset *a) { ('.' | 'l' << 8 | 'u' << 16 | 'a' << 24)) { return true; } - p = ZIP_CFILE_NAME(zbase + a->cf); - n = ZIP_CFILE_NAMESIZE(zbase + a->cf); + p = ZIP_CFILE_NAME(zmap + a->cf); + n = ZIP_CFILE_NAMESIZE(zmap + a->cf); return n > 4 && READ32LE(p + n - 4) == ('.' | 'l' << 8 | 'u' << 16 | 'a' << 24); } @@ -6124,8 +6114,8 @@ static const char *GetContentType(struct Asset *a, const char *path, size_t n) { } return firstnonnull( GetContentTypeExt(path, n), - firstnonnull(GetContentTypeExt(ZIP_CFILE_NAME(zbase + a->cf), - ZIP_CFILE_NAMESIZE(zbase + a->cf)), + firstnonnull(GetContentTypeExt(ZIP_CFILE_NAME(zmap + a->cf), + ZIP_CFILE_NAMESIZE(zmap + a->cf)), a->istext ? "text/plain" : "application/octet-stream")); } @@ -6147,8 +6137,8 @@ static char *ServeAsset(struct Asset *a, const char *path, size_t pathlen) { p = SetStatus(304, "Not Modified"); } else { if (!a->file) { - cpm.content = (char *)ZIP_LFILE_CONTENT(zbase + a->lf); - cpm.contentlength = GetZipCfileCompressedSize(zbase + a->cf); + cpm.content = (char *)ZIP_LFILE_CONTENT(zmap + a->lf); + cpm.contentlength = GetZipCfileCompressedSize(zmap + a->cf); } else if ((p = OpenAsset(a))) { return p; } @@ -6164,7 +6154,7 @@ static char *ServeAsset(struct Asset *a, const char *path, size_t pathlen) { LockInc(&shared->c.identityresponses); DEBUGF("(zip) ServeAssetZipIdentity(%`'s)", ct); if (Verify(cpm.content, cpm.contentlength, - ZIP_LFILE_CRC32(zbase + a->lf))) { + ZIP_LFILE_CRC32(zmap + a->lf))) { p = SetStatus(200, "OK"); } else { return ServeError(500, "Internal Server Error");