mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Remove old zip base skew hack
Since 8ff48201ca
we no longer need the
hack where, when running .com.dbg files, we scanned for the embedded
.com file offset, and then computed zip offsets realtive to that. It
wasn't very reliable in the first place, and was causing issues with
running our new .com.dbg executables, which are true zip files.
This commit is contained in:
parent
207e18a060
commit
52d28966f7
10 changed files with 134 additions and 238 deletions
|
@ -39,8 +39,8 @@ int __negvsi2(int x) {
|
||||||
* @see __on_arithmetic_overflow()
|
* @see __on_arithmetic_overflow()
|
||||||
* @see -ftrapv to enable
|
* @see -ftrapv to enable
|
||||||
*/
|
*/
|
||||||
long __negvdi2(long x) {
|
long long __negvdi2(long long x) {
|
||||||
if (x == LONG_MIN) {
|
if (x == LLONG_MIN) {
|
||||||
__on_arithmetic_overflow();
|
__on_arithmetic_overflow();
|
||||||
}
|
}
|
||||||
return -x;
|
return -x;
|
||||||
|
@ -79,8 +79,8 @@ int __addvsi3(int x, int y) {
|
||||||
* @see __on_arithmetic_overflow()
|
* @see __on_arithmetic_overflow()
|
||||||
* @see -ftrapv to enable
|
* @see -ftrapv to enable
|
||||||
*/
|
*/
|
||||||
long __addvdi3(long x, long y) {
|
long long __addvdi3(long long x, long long y) {
|
||||||
long z;
|
long long z;
|
||||||
if (ckd_add(&z, x, y)) {
|
if (ckd_add(&z, x, y)) {
|
||||||
__on_arithmetic_overflow();
|
__on_arithmetic_overflow();
|
||||||
}
|
}
|
||||||
|
@ -121,8 +121,8 @@ int __subvsi3(int x, int y) {
|
||||||
* @see __on_arithmetic_overflow()
|
* @see __on_arithmetic_overflow()
|
||||||
* @see -ftrapv to enable
|
* @see -ftrapv to enable
|
||||||
*/
|
*/
|
||||||
long __subvdi3(long x, long y) {
|
long long __subvdi3(long long x, long long y) {
|
||||||
long z;
|
long long z;
|
||||||
if (ckd_sub(&z, x, y)) {
|
if (ckd_sub(&z, x, y)) {
|
||||||
__on_arithmetic_overflow();
|
__on_arithmetic_overflow();
|
||||||
}
|
}
|
||||||
|
@ -163,22 +163,8 @@ int __mulvsi3(int x, int y) {
|
||||||
* @see __on_arithmetic_overflow()
|
* @see __on_arithmetic_overflow()
|
||||||
* @see -ftrapv to enable
|
* @see -ftrapv to enable
|
||||||
*/
|
*/
|
||||||
long __mulvdi3(long x, long y) {
|
long long __mulvdi3(long long x, long long y) {
|
||||||
long z;
|
long 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;
|
|
||||||
if (ckd_mul(&z, x, y)) {
|
if (ckd_mul(&z, x, y)) {
|
||||||
__on_arithmetic_overflow();
|
__on_arithmetic_overflow();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
/*-*- 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│
|
│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 │
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
│ any purpose with or without fee is hereby granted, provided that the │
|
│ 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 │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/intrin/bits.h"
|
#include "libc/runtime/internal.h"
|
||||||
#include "libc/log/libfatal.internal.h"
|
|
||||||
#include "libc/macros.internal.h"
|
|
||||||
#include "libc/str/str.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
|
* @see __on_arithmetic_overflow()
|
||||||
* gone through the `objcopy -S -O binary` step. We make the assumption
|
* @see -ftrapv to enable
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
uint8_t *FindEmbeddedApe(const uint8_t *p, size_t n) {
|
int128_t __mulvti3(int128_t x, int128_t y) {
|
||||||
size_t i;
|
int o;
|
||||||
uint64_t w;
|
int128_t z;
|
||||||
n = MIN(n, TRIES * PAGESIZE);
|
z = __muloti4(x, y, &o);
|
||||||
for (i = 0; i + 8 <= n; i += PAGESIZE) {
|
if (o) __on_arithmetic_overflow();
|
||||||
w = READ64LE(p + i);
|
return z;
|
||||||
if (w == READ64LE("MZqFpD='") || w == READ64LE("\177ELF\2\1\1\11")) {
|
|
||||||
return (/*unconst*/ uint8_t *)(p + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
|
@ -16,12 +16,14 @@
|
||||||
│ 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/stdckdint.h"
|
||||||
#include "libc/zip.internal.h"
|
#include "libc/zip.internal.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if ZIP EOCD record seems legit.
|
* Determines if ZIP EOCD record seems legit.
|
||||||
*/
|
*/
|
||||||
int IsZipEocd32(const uint8_t *p, size_t n, size_t i) {
|
int IsZipEocd32(const uint8_t *p, size_t n, size_t i) {
|
||||||
|
size_t offset;
|
||||||
if (i > n || n - i < kZipCdirHdrMinSize) {
|
if (i > n || n - i < kZipCdirHdrMinSize) {
|
||||||
return kZipErrorEocdOffsetOverflow;
|
return kZipErrorEocdOffsetOverflow;
|
||||||
}
|
}
|
||||||
|
@ -35,12 +37,15 @@ int IsZipEocd32(const uint8_t *p, size_t n, size_t i) {
|
||||||
return kZipErrorEocdDiskMismatch;
|
return kZipErrorEocdDiskMismatch;
|
||||||
}
|
}
|
||||||
if (ZIP_CDIR_RECORDSONDISK(p + i) != ZIP_CDIR_RECORDS(p + i)) {
|
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)) {
|
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 kZipErrorCdirOffsetPastEocd;
|
||||||
}
|
}
|
||||||
return kZipOk;
|
return kZipOk;
|
||||||
|
|
|
@ -16,34 +16,41 @@
|
||||||
│ 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/stdckdint.h"
|
||||||
#include "libc/zip.internal.h"
|
#include "libc/zip.internal.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns kZipOk if zip64 end of central directory header seems legit.
|
* Returns kZipOk if zip64 end of central directory header seems legit.
|
||||||
*/
|
*/
|
||||||
int IsZipEocd64(const uint8_t *p, size_t n, size_t i) {
|
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;
|
return kZipErrorEocdOffsetOverflow;
|
||||||
}
|
}
|
||||||
if (READ32LE(p + i) != kZipCdir64HdrMagic) {
|
if (READ32LE(p + i) != kZipCdir64HdrMagic) {
|
||||||
return kZipErrorEocdMagicNotFound;
|
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;
|
return kZipErrorEocdSizeOverflow;
|
||||||
}
|
}
|
||||||
if (ZIP_LOCATE64_MAGIC(p + i + ZIP_CDIR64_HDRSIZE(p + i)) !=
|
if (ZIP_LOCATE64_MAGIC(p + loc) != kZipCdir64LocatorMagic) {
|
||||||
kZipCdir64LocatorMagic) {
|
return kZipErrorEocdLocatorMagic;
|
||||||
return kZipErrorCdirLocatorMagic;
|
|
||||||
}
|
}
|
||||||
if (ZIP_LOCATE64_OFFSET(p + i + ZIP_CDIR64_HDRSIZE(p + i)) != i) {
|
if (ZIP_LOCATE64_OFFSET(p + loc) != i) {
|
||||||
return kZipErrorCdirLocatorOffset;
|
return kZipErrorEocdLocatorOffset;
|
||||||
}
|
}
|
||||||
if (ZIP_CDIR64_RECORDS(p + i) * kZipCfileHdrMinSize >
|
if (ckd_add(&off, ZIP_CDIR64_OFFSET(p + i), ZIP_CDIR64_SIZE(p + i))) {
|
||||||
ZIP_CDIR64_SIZE(p + i)) {
|
return kZipErrorEocdOffsetSizeOverflow;
|
||||||
return kZipErrorCdirRecordsOverflow;
|
|
||||||
}
|
}
|
||||||
if (ZIP_CDIR64_OFFSET(p + i) + ZIP_CDIR64_SIZE(p + i) > i) {
|
if (off > i) {
|
||||||
return kZipErrorCdirOffsetPastEocd;
|
return kZipErrorCdirOffsetPastEocd;
|
||||||
}
|
}
|
||||||
|
if (ckd_mul(&cdsize, ZIP_CDIR64_RECORDS(p + i), kZipCfileHdrMinSize) ||
|
||||||
|
cdsize > ZIP_CDIR64_SIZE(p + i)) {
|
||||||
|
return kZipErrorEocdRecordsOverflow;
|
||||||
|
}
|
||||||
return kZipOk;
|
return kZipOk;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,20 +15,27 @@
|
||||||
#define ZM_(x) ~VEIL("r", ~x) /* prevent magic from appearing in binary */
|
#define ZM_(x) ~VEIL("r", ~x) /* prevent magic from appearing in binary */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define kZipOk 0
|
#ifdef TINY
|
||||||
#define kZipErrorEocdNotFound -1
|
#define _ZE(x) -1
|
||||||
#define kZipErrorEocdOffsetOverflow -2
|
#else
|
||||||
#define kZipErrorEocdMagicNotFound -3
|
#define _ZE(x) x
|
||||||
#define kZipErrorEocdSizeOverflow -4
|
#endif
|
||||||
#define kZipErrorEocdDiskMismatch -5
|
|
||||||
#define kZipErrorCdirRecordsMismatch -6
|
#define kZipOk 0
|
||||||
#define kZipErrorCdirRecordsOverflow -7
|
#define kZipErrorEocdNotFound _ZE(-1)
|
||||||
#define kZipErrorCdirOffsetPastEocd -8
|
#define kZipErrorEocdOffsetOverflow _ZE(-2)
|
||||||
#define kZipErrorCdirLocatorMagic -9
|
#define kZipErrorEocdMagicNotFound _ZE(-3)
|
||||||
#define kZipErrorCdirLocatorOffset -10
|
#define kZipErrorEocdSizeOverflow _ZE(-4)
|
||||||
#define kZipErrorRaceCondition -11
|
#define kZipErrorEocdDiskMismatch _ZE(-5)
|
||||||
#define kZipErrorMapFailed -12
|
#define kZipErrorEocdOffsetSizeOverflow _ZE(-6)
|
||||||
#define kZipErrorOpenFailed -13
|
#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
|
#define kZipCosmopolitanVersion kZipEra2001
|
||||||
|
|
||||||
|
@ -75,7 +82,7 @@
|
||||||
#define kZipCdirOffsetOffset 16
|
#define kZipCdirOffsetOffset 16
|
||||||
#define kZipCdirCommentSizeOffset 20
|
#define kZipCdirCommentSizeOffset 20
|
||||||
|
|
||||||
#define kZipCdir64HdrMagic ZM_(0x06064b50) /* PK♣♠ "PK\6\6" */
|
#define kZipCdir64HdrMagic ZM_(0x06064b50) /* PK♠♠ "PK\6\6" */
|
||||||
#define kZipCdir64HdrMinSize 56
|
#define kZipCdir64HdrMinSize 56
|
||||||
#define kZipCdir64LocatorMagic ZM_(0x07064b50) /* PK♠• "PK\6\7" */
|
#define kZipCdir64LocatorMagic ZM_(0x07064b50) /* PK♠• "PK\6\7" */
|
||||||
#define kZipCdir64LocatorSize 20
|
#define kZipCdir64LocatorSize 20
|
||||||
|
@ -211,7 +218,6 @@
|
||||||
#define ZIP_EXTRA_SIZE(P) (ZIP_EXTRA_CONTENTSIZE(P) + kZipExtraHdrSize)
|
#define ZIP_EXTRA_SIZE(P) (ZIP_EXTRA_CONTENTSIZE(P) + kZipExtraHdrSize)
|
||||||
|
|
||||||
void *GetZipEocd(const void *, size_t, int *);
|
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 IsZipEocd32(const uint8_t *, size_t, size_t);
|
||||||
int IsZipEocd64(const uint8_t *, size_t, size_t);
|
int IsZipEocd64(const uint8_t *, size_t, size_t);
|
||||||
int GetZipCfileMode(const uint8_t *);
|
int GetZipCfileMode(const uint8_t *);
|
||||||
|
|
|
@ -67,9 +67,9 @@ struct Zipos *__zipos_get(void) {
|
||||||
int fd, err, msg;
|
int fd, err, msg;
|
||||||
static bool once;
|
static bool once;
|
||||||
struct Zipos *res;
|
struct Zipos *res;
|
||||||
|
uint8_t *map, *cdir;
|
||||||
const char *progpath;
|
const char *progpath;
|
||||||
static struct Zipos zipos;
|
static struct Zipos zipos;
|
||||||
uint8_t *map, *base, *cdir;
|
|
||||||
__zipos_lock();
|
__zipos_lock();
|
||||||
if (!once) {
|
if (!once) {
|
||||||
progpath = getenv("COSMOPOLITAN_INIT_ZIPOS");
|
progpath = getenv("COSMOPOLITAN_INIT_ZIPOS");
|
||||||
|
@ -86,15 +86,11 @@ struct Zipos *__zipos_get(void) {
|
||||||
}
|
}
|
||||||
if (fd != -1) {
|
if (fd != -1) {
|
||||||
if ((size = lseek(fd, 0, SEEK_END)) != -1 &&
|
if ((size = lseek(fd, 0, SEEK_END)) != -1 &&
|
||||||
(map = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0)) != MAP_FAILED) {
|
(map = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0)) !=
|
||||||
if ((base = FindEmbeddedApe(map, size))) {
|
MAP_FAILED) {
|
||||||
size -= base - map;
|
if ((cdir = GetZipEocd(map, size, &err))) {
|
||||||
} else {
|
__zipos_munmap_unneeded(map, cdir, map);
|
||||||
base = map;
|
zipos.map = map;
|
||||||
}
|
|
||||||
if ((cdir = GetZipEocd(base, size, &err)) &&
|
|
||||||
_cmpxchg(&zipos.map, 0, base)) {
|
|
||||||
__zipos_munmap_unneeded(base, cdir, map);
|
|
||||||
zipos.cdir = cdir;
|
zipos.cdir = cdir;
|
||||||
msg = kZipOk;
|
msg = kZipOk;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -123,12 +123,15 @@ static void CopyZip(void) {
|
||||||
unsigned char *ineof, *stop, *eocd, *cdir, *lfile, *cfile;
|
unsigned char *ineof, *stop, *eocd, *cdir, *lfile, *cfile;
|
||||||
|
|
||||||
// find zip eocd header
|
// find zip eocd header
|
||||||
ineof = (unsigned char *)inmap + insize;
|
ineof = inmap + insize;
|
||||||
eocd = ineof - kZipCdirHdrMinSize;
|
eocd = ineof - kZipCdirHdrMinSize;
|
||||||
stop = MAX(eocd - 65536, inmap);
|
stop = MAX(eocd - 65536, inmap);
|
||||||
for (;; --eocd) {
|
for (;; --eocd) {
|
||||||
if (eocd < stop) return;
|
if (eocd < stop) return;
|
||||||
if (READ32LE(eocd) == kZipCdirHdrMagic) {
|
if (READ32LE(eocd) == kZipCdirHdrMagic) {
|
||||||
|
if (IsZipEocd32(inmap, insize, eocd - inmap) != kZipOk) {
|
||||||
|
Die(inpath, "found bad eocd record");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -430,10 +430,6 @@ void DisassembleZip(const char *path, uint8_t *p, size_t n) {
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
static int records;
|
static int records;
|
||||||
uint8_t *eocd32, *eocd64, *cdir, *cf, *lf, *q;
|
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);
|
eocd32 = GetZipCdir32(p, n);
|
||||||
eocd64 = GetZipCdir64(p, n);
|
eocd64 = GetZipCdir64(p, n);
|
||||||
CHECK(eocd32 || eocd64);
|
CHECK(eocd32 || eocd64);
|
||||||
|
|
|
@ -482,7 +482,6 @@ static size_t zsize;
|
||||||
static lua_State *GL;
|
static lua_State *GL;
|
||||||
static lua_State *YL;
|
static lua_State *YL;
|
||||||
static uint8_t *zmap;
|
static uint8_t *zmap;
|
||||||
static uint8_t *zbase;
|
|
||||||
static uint8_t *zcdir;
|
static uint8_t *zcdir;
|
||||||
static size_t hdrsize;
|
static size_t hdrsize;
|
||||||
static size_t amtread;
|
static size_t amtread;
|
||||||
|
@ -2089,11 +2088,11 @@ static int64_t GetGmtOffset(int64_t t) {
|
||||||
|
|
||||||
forceinline bool IsCompressed(struct Asset *a) {
|
forceinline bool IsCompressed(struct Asset *a) {
|
||||||
return !a->file &&
|
return !a->file &&
|
||||||
ZIP_LFILE_COMPRESSIONMETHOD(zbase + a->lf) == kZipCompressionDeflate;
|
ZIP_LFILE_COMPRESSIONMETHOD(zmap + a->lf) == kZipCompressionDeflate;
|
||||||
}
|
}
|
||||||
|
|
||||||
forceinline int GetMode(struct Asset *a) {
|
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) {
|
forceinline bool IsCompressionMethodSupported(int method) {
|
||||||
|
@ -2140,26 +2139,25 @@ static void IndexAssets(void) {
|
||||||
n = GetZipCdirRecords(zcdir);
|
n = GetZipCdirRecords(zcdir);
|
||||||
m = _roundup2pow(MAX(1, n) * HASH_LOAD_FACTOR);
|
m = _roundup2pow(MAX(1, n) * HASH_LOAD_FACTOR);
|
||||||
p = xcalloc(m, sizeof(struct Asset));
|
p = xcalloc(m, sizeof(struct Asset));
|
||||||
for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zbase + cf)) {
|
for (cf = GetZipCdirOffset(zcdir); n--; cf += ZIP_CFILE_HDRSIZE(zmap + cf)) {
|
||||||
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zbase + cf));
|
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zmap + cf));
|
||||||
if (!IsCompressionMethodSupported(
|
if (!IsCompressionMethodSupported(ZIP_CFILE_COMPRESSIONMETHOD(zmap + cf))) {
|
||||||
ZIP_CFILE_COMPRESSIONMETHOD(zbase + cf))) {
|
|
||||||
WARNF("(zip) don't understand zip compression method %d used by %`'.*s",
|
WARNF("(zip) don't understand zip compression method %d used by %`'.*s",
|
||||||
ZIP_CFILE_COMPRESSIONMETHOD(zbase + cf),
|
ZIP_CFILE_COMPRESSIONMETHOD(zmap + cf),
|
||||||
ZIP_CFILE_NAMESIZE(zbase + cf), ZIP_CFILE_NAME(zbase + cf));
|
ZIP_CFILE_NAMESIZE(zmap + cf), ZIP_CFILE_NAME(zmap + cf));
|
||||||
continue;
|
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;
|
step = 0;
|
||||||
do {
|
do {
|
||||||
i = (hash + (step * (step + 1)) >> 1) & (m - 1);
|
i = (hash + (step * (step + 1)) >> 1) & (m - 1);
|
||||||
++step;
|
++step;
|
||||||
} while (p[i].hash);
|
} while (p[i].hash);
|
||||||
GetZipCfileTimestamps(zbase + cf, &lm, 0, 0, gmtoff);
|
GetZipCfileTimestamps(zmap + cf, &lm, 0, 0, gmtoff);
|
||||||
p[i].hash = hash;
|
p[i].hash = hash;
|
||||||
p[i].cf = cf;
|
p[i].cf = cf;
|
||||||
p[i].lf = GetZipCfileOffset(zbase + cf);
|
p[i].lf = GetZipCfileOffset(zmap + cf);
|
||||||
p[i].istext = !!(ZIP_CFILE_INTERNALATTRIBUTES(zbase + cf) & kZipIattrText);
|
p[i].istext = !!(ZIP_CFILE_INTERNALATTRIBUTES(zmap + cf) & kZipIattrText);
|
||||||
p[i].lastmodified = lm.tv_sec;
|
p[i].lastmodified = lm.tv_sec;
|
||||||
p[i].lastmodifiedstr = FormatUnixHttpDateTime(xmalloc(30), lm.tv_sec);
|
p[i].lastmodifiedstr = FormatUnixHttpDateTime(xmalloc(30), lm.tv_sec);
|
||||||
}
|
}
|
||||||
|
@ -2171,7 +2169,7 @@ static bool OpenZip(bool force) {
|
||||||
int fd;
|
int fd;
|
||||||
size_t n;
|
size_t n;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
uint8_t *m, *b, *d, *p;
|
uint8_t *m, *d, *p;
|
||||||
if (stat(zpath, &st) != -1) {
|
if (stat(zpath, &st) != -1) {
|
||||||
if (force || st.st_ino != zst.st_ino || st.st_size > zst.st_size) {
|
if (force || st.st_ino != zst.st_ino || st.st_size > zst.st_size) {
|
||||||
if (st.st_ino == zst.st_ino) {
|
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)) !=
|
if ((m = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) !=
|
||||||
MAP_FAILED) {
|
MAP_FAILED) {
|
||||||
n = st.st_size;
|
n = st.st_size;
|
||||||
if ((p = FindEmbeddedApe(m, n))) {
|
if ((d = GetZipEocd(m, n, 0))) {
|
||||||
b = p;
|
|
||||||
n -= p - m;
|
|
||||||
} else {
|
|
||||||
b = m;
|
|
||||||
}
|
|
||||||
if ((d = GetZipEocd(b, n, 0))) {
|
|
||||||
if (zmap) {
|
if (zmap) {
|
||||||
LOGIFNEG1(munmap(zmap, zbase + zsize - zmap));
|
LOGIFNEG1(munmap(zmap, zsize));
|
||||||
}
|
}
|
||||||
zmap = m;
|
zmap = m;
|
||||||
zbase = b;
|
|
||||||
zsize = n;
|
zsize = n;
|
||||||
zcdir = d;
|
zcdir = d;
|
||||||
DCHECK(IsZipEocd32(zbase, zsize, zcdir - zbase) == kZipOk ||
|
DCHECK(IsZipEocd32(zmap, zsize, zcdir - zmap) == kZipOk ||
|
||||||
IsZipEocd64(zbase, zsize, zcdir - zbase) == kZipOk);
|
IsZipEocd64(zmap, zsize, zcdir - zmap) == kZipOk);
|
||||||
memcpy(&zst, &st, sizeof(st));
|
memcpy(&zst, &st, sizeof(st));
|
||||||
IndexAssets();
|
IndexAssets();
|
||||||
return true;
|
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);
|
i = (hash + (step * (step + 1)) >> 1) & (assets.n - 1);
|
||||||
if (!assets.p[i].hash) return NULL;
|
if (!assets.p[i].hash) return NULL;
|
||||||
if (hash == assets.p[i].hash &&
|
if (hash == assets.p[i].hash &&
|
||||||
pathlen == ZIP_CFILE_NAMESIZE(zbase + assets.p[i].cf) &&
|
pathlen == ZIP_CFILE_NAMESIZE(zmap + assets.p[i].cf) &&
|
||||||
memcmp(path, ZIP_CFILE_NAME(zbase + assets.p[i].cf), pathlen) == 0) {
|
memcmp(path, ZIP_CFILE_NAME(zmap + assets.p[i].cf), pathlen) == 0) {
|
||||||
return &assets.p[i];
|
return &assets.p[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2378,18 +2369,18 @@ static void *LoadAsset(struct Asset *a, size_t *out_size) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!a->file) {
|
if (!a->file) {
|
||||||
size = GetZipLfileUncompressedSize(zbase + a->lf);
|
size = GetZipLfileUncompressedSize(zmap + a->lf);
|
||||||
if (size == SIZE_MAX || !(data = malloc(size + 1))) return NULL;
|
if (size == SIZE_MAX || !(data = malloc(size + 1))) return NULL;
|
||||||
if (IsCompressed(a)) {
|
if (IsCompressed(a)) {
|
||||||
if (!Inflate(data, size, ZIP_LFILE_CONTENT(zbase + a->lf),
|
if (!Inflate(data, size, ZIP_LFILE_CONTENT(zmap + a->lf),
|
||||||
GetZipCfileCompressedSize(zbase + a->cf))) {
|
GetZipCfileCompressedSize(zmap + a->cf))) {
|
||||||
free(data);
|
free(data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
free(data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2536,10 +2527,10 @@ static char *ServeErrorImpl(unsigned code, const char *reason,
|
||||||
cpm.content = FreeLater(xslurp(a->file->path.s, &cpm.contentlength));
|
cpm.content = FreeLater(xslurp(a->file->path.s, &cpm.contentlength));
|
||||||
return AppendContentType(p, "text/html; charset=utf-8");
|
return AppendContentType(p, "text/html; charset=utf-8");
|
||||||
} else {
|
} else {
|
||||||
cpm.content = (char *)ZIP_LFILE_CONTENT(zbase + a->lf);
|
cpm.content = (char *)ZIP_LFILE_CONTENT(zmap + a->lf);
|
||||||
cpm.contentlength = GetZipCfileCompressedSize(zbase + a->cf);
|
cpm.contentlength = GetZipCfileCompressedSize(zmap + a->cf);
|
||||||
if (IsCompressed(a)) {
|
if (IsCompressed(a)) {
|
||||||
n = GetZipLfileUncompressedSize(zbase + a->lf);
|
n = GetZipLfileUncompressedSize(zmap + a->lf);
|
||||||
if ((s = FreeLater(malloc(n))) &&
|
if ((s = FreeLater(malloc(n))) &&
|
||||||
Inflate(s, n, cpm.content, cpm.contentlength)) {
|
Inflate(s, n, cpm.content, cpm.contentlength)) {
|
||||||
cpm.content = s;
|
cpm.content = s;
|
||||||
|
@ -2548,8 +2539,7 @@ static char *ServeErrorImpl(unsigned code, const char *reason,
|
||||||
return ServeDefaultErrorPage(p, code, reason, details);
|
return ServeDefaultErrorPage(p, code, reason, details);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Verify(cpm.content, cpm.contentlength,
|
if (Verify(cpm.content, cpm.contentlength, ZIP_LFILE_CRC32(zmap + a->lf))) {
|
||||||
ZIP_LFILE_CRC32(zbase + a->lf))) {
|
|
||||||
return AppendContentType(p, "text/html; charset=utf-8");
|
return AppendContentType(p, "text/html; charset=utf-8");
|
||||||
} else {
|
} else {
|
||||||
return ServeDefaultErrorPage(p, code, reason, details);
|
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;
|
dg.t = dg.s.avail_out ? 1 : 2;
|
||||||
} else if (rc == Z_STREAM_END) {
|
} else if (rc == Z_STREAM_END) {
|
||||||
CHECK_EQ(Z_OK, inflateEnd(&dg.s));
|
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;
|
dg.t = 3;
|
||||||
}
|
}
|
||||||
return v[0].iov_len + v[1].iov_len + v[2].iov_len;
|
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;
|
uint32_t crc;
|
||||||
LockInc(&shared->c.inflates);
|
LockInc(&shared->c.inflates);
|
||||||
LockInc(&shared->c.decompressedresponses);
|
LockInc(&shared->c.decompressedresponses);
|
||||||
size = GetZipCfileUncompressedSize(zbase + a->cf);
|
size = GetZipCfileUncompressedSize(zmap + a->cf);
|
||||||
DEBUGF("(srvr) ServeAssetDecompressed(%ld)→%ld", cpm.contentlength, size);
|
DEBUGF("(srvr) ServeAssetDecompressed(%ld)→%ld", cpm.contentlength, size);
|
||||||
if (cpm.msg.method == kHttpHead) {
|
if (cpm.msg.method == kHttpHead) {
|
||||||
cpm.content = 0;
|
cpm.content = 0;
|
||||||
|
@ -2777,7 +2767,7 @@ static char *ServeAssetDecompressed(struct Asset *a) {
|
||||||
return SetStatus(200, "OK");
|
return SetStatus(200, "OK");
|
||||||
} else if ((p = FreeLater(malloc(size))) &&
|
} else if ((p = FreeLater(malloc(size))) &&
|
||||||
Inflate(p, size, cpm.content, cpm.contentlength) &&
|
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.content = p;
|
||||||
cpm.contentlength = size;
|
cpm.contentlength = size;
|
||||||
return SetStatus(200, "OK");
|
return SetStatus(200, "OK");
|
||||||
|
@ -2797,8 +2787,8 @@ static inline char *ServeAssetPrecompressed(struct Asset *a) {
|
||||||
uint32_t crc;
|
uint32_t crc;
|
||||||
DEBUGF("(srvr) ServeAssetPrecompressed()");
|
DEBUGF("(srvr) ServeAssetPrecompressed()");
|
||||||
LockInc(&shared->c.precompressedresponses);
|
LockInc(&shared->c.precompressedresponses);
|
||||||
crc = ZIP_CFILE_CRC32(zbase + a->cf);
|
crc = ZIP_CFILE_CRC32(zmap + a->cf);
|
||||||
size = GetZipCfileUncompressedSize(zbase + a->cf);
|
size = GetZipCfileUncompressedSize(zmap + a->cf);
|
||||||
cpm.gzipped = size;
|
cpm.gzipped = size;
|
||||||
WRITE32LE(gzip_footer + 0, crc);
|
WRITE32LE(gzip_footer + 0, crc);
|
||||||
WRITE32LE(gzip_footer + 4, size);
|
WRITE32LE(gzip_footer + 4, size);
|
||||||
|
@ -3005,7 +2995,7 @@ td { padding-right: 3em; }\r\n\
|
||||||
GetZipCdirComment(zcdir));
|
GetZipCdirComment(zcdir));
|
||||||
bzero(w, sizeof(w));
|
bzero(w, sizeof(w));
|
||||||
n = GetZipCdirRecords(zcdir);
|
n = GetZipCdirRecords(zcdir);
|
||||||
for (zcf = zbase + GetZipCdirOffset(zcdir); n--;
|
for (zcf = zmap + GetZipCdirOffset(zcdir); n--;
|
||||||
zcf += ZIP_CFILE_HDRSIZE(zcf)) {
|
zcf += ZIP_CFILE_HDRSIZE(zcf)) {
|
||||||
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zcf));
|
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zcf));
|
||||||
path = GetAssetPath(zcf, &pathlen);
|
path = GetAssetPath(zcf, &pathlen);
|
||||||
|
@ -3017,7 +3007,7 @@ td { padding-right: 3em; }\r\n\
|
||||||
free(path);
|
free(path);
|
||||||
}
|
}
|
||||||
n = GetZipCdirRecords(zcdir);
|
n = GetZipCdirRecords(zcdir);
|
||||||
for (zcf = zbase + GetZipCdirOffset(zcdir); n--;
|
for (zcf = zmap + GetZipCdirOffset(zcdir); n--;
|
||||||
zcf += ZIP_CFILE_HDRSIZE(zcf)) {
|
zcf += ZIP_CFILE_HDRSIZE(zcf)) {
|
||||||
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zcf));
|
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zcf));
|
||||||
path = GetAssetPath(zcf, &pathlen);
|
path = GetAssetPath(zcf, &pathlen);
|
||||||
|
@ -3590,9 +3580,9 @@ static int LuaLoadAsset(lua_State *L) {
|
||||||
if ((a = GetAsset(path, pathlen))) {
|
if ((a = GetAsset(path, pathlen))) {
|
||||||
if (!a->file && !IsCompressed(a)) {
|
if (!a->file && !IsCompressed(a)) {
|
||||||
/* fast path: this avoids extra copy */
|
/* fast path: this avoids extra copy */
|
||||||
data = ZIP_LFILE_CONTENT(zbase + a->lf);
|
data = ZIP_LFILE_CONTENT(zmap + a->lf);
|
||||||
size = GetZipLfileUncompressedSize(zbase + a->lf);
|
size = GetZipLfileUncompressedSize(zmap + a->lf);
|
||||||
if (Verify(data, size, ZIP_LFILE_CRC32(zbase + a->lf))) {
|
if (Verify(data, size, ZIP_LFILE_CRC32(zmap + a->lf))) {
|
||||||
lua_pushlstring(L, data, size);
|
lua_pushlstring(L, data, size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -3711,15 +3701,15 @@ static void StoreAsset(char *path, size_t pathlen, char *data, size_t datalen,
|
||||||
if (a) {
|
if (a) {
|
||||||
// to remove an existing asset,
|
// to remove an existing asset,
|
||||||
// first copy the central directory part before its record
|
// 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;
|
v[4].iov_len = a->cf - oldcdiroffset;
|
||||||
// and then the rest of the central directory
|
// and then the rest of the central directory
|
||||||
v[5].iov_base = zbase + oldcdiroffset +
|
v[5].iov_base =
|
||||||
(v[4].iov_len + ZIP_CFILE_HDRSIZE(zbase + a->cf));
|
zmap + oldcdiroffset + (v[4].iov_len + ZIP_CFILE_HDRSIZE(zmap + a->cf));
|
||||||
v[5].iov_len =
|
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 {
|
} else {
|
||||||
v[4].iov_base = zbase + oldcdiroffset;
|
v[4].iov_base = zmap + oldcdiroffset;
|
||||||
v[4].iov_len = oldcdirsize;
|
v[4].iov_len = oldcdirsize;
|
||||||
v[5].iov_base = 0;
|
v[5].iov_base = 0;
|
||||||
v[5].iov_len = 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(cdirsize, 0xffffffff));
|
||||||
p = WRITE32LE(p, MIN(cdiroffset, 0xffffffff));
|
p = WRITE32LE(p, MIN(cdiroffset, 0xffffffff));
|
||||||
p = WRITE16LE(p, v[12].iov_len);
|
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, WritevAll(zfd, v, 13));
|
||||||
CHECK_NE(-1, fcntl(zfd, F_SETLK, &(struct flock){F_UNLCK}));
|
CHECK_NE(-1, fcntl(zfd, F_SETLK, &(struct flock){F_UNLCK}));
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -4718,7 +4708,7 @@ static int LuaGetZipPaths(lua_State *L) {
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
i = 0;
|
i = 0;
|
||||||
n = GetZipCdirRecords(zcdir);
|
n = GetZipCdirRecords(zcdir);
|
||||||
for (zcf = zbase + GetZipCdirOffset(zcdir); n--;
|
for (zcf = zmap + GetZipCdirOffset(zcdir); n--;
|
||||||
zcf += ZIP_CFILE_HDRSIZE(zcf)) {
|
zcf += ZIP_CFILE_HDRSIZE(zcf)) {
|
||||||
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zcf));
|
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(zcf));
|
||||||
path = GetAssetPath(zcf, &pathlen);
|
path = GetAssetPath(zcf, &pathlen);
|
||||||
|
@ -4755,7 +4745,7 @@ static int LuaGetAssetLastModifiedTime(lua_State *L) {
|
||||||
if (a->file) {
|
if (a->file) {
|
||||||
zuluseconds = a->file->st.st_mtim.tv_sec;
|
zuluseconds = a->file->st.st_mtim.tv_sec;
|
||||||
} else {
|
} else {
|
||||||
GetZipCfileTimestamps(zbase + a->cf, &lm, 0, 0, gmtoff);
|
GetZipCfileTimestamps(zmap + a->cf, &lm, 0, 0, gmtoff);
|
||||||
zuluseconds = lm.tv_sec;
|
zuluseconds = lm.tv_sec;
|
||||||
}
|
}
|
||||||
lua_pushinteger(L, zuluseconds);
|
lua_pushinteger(L, zuluseconds);
|
||||||
|
@ -4774,7 +4764,7 @@ static int LuaGetAssetSize(lua_State *L) {
|
||||||
if (a->file) {
|
if (a->file) {
|
||||||
lua_pushinteger(L, a->file->st.st_size);
|
lua_pushinteger(L, a->file->st.st_size);
|
||||||
} else {
|
} else {
|
||||||
lua_pushinteger(L, GetZipLfileUncompressedSize(zbase + a->lf));
|
lua_pushinteger(L, GetZipLfileUncompressedSize(zmap + a->lf));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
|
@ -5004,9 +4994,9 @@ static int LuaGetAssetComment(lua_State *L) {
|
||||||
size_t pathlen, m;
|
size_t pathlen, m;
|
||||||
path = LuaCheckPath(L, 1, &pathlen);
|
path = LuaCheckPath(L, 1, &pathlen);
|
||||||
if ((a = GetAssetZip(path, pathlen)) &&
|
if ((a = GetAssetZip(path, pathlen)) &&
|
||||||
(m = strnlen(ZIP_CFILE_COMMENT(zbase + a->cf),
|
(m = strnlen(ZIP_CFILE_COMMENT(zmap + a->cf),
|
||||||
ZIP_CFILE_COMMENTSIZE(zbase + a->cf)))) {
|
ZIP_CFILE_COMMENTSIZE(zmap + a->cf)))) {
|
||||||
lua_pushlstring(L, ZIP_CFILE_COMMENT(zbase + a->cf), m);
|
lua_pushlstring(L, ZIP_CFILE_COMMENT(zmap + a->cf), m);
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
}
|
}
|
||||||
|
@ -6094,8 +6084,8 @@ static inline bool IsLua(struct Asset *a) {
|
||||||
('.' | 'l' << 8 | 'u' << 16 | 'a' << 24)) {
|
('.' | 'l' << 8 | 'u' << 16 | 'a' << 24)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
p = ZIP_CFILE_NAME(zbase + a->cf);
|
p = ZIP_CFILE_NAME(zmap + a->cf);
|
||||||
n = ZIP_CFILE_NAMESIZE(zbase + a->cf);
|
n = ZIP_CFILE_NAMESIZE(zmap + a->cf);
|
||||||
return n > 4 &&
|
return n > 4 &&
|
||||||
READ32LE(p + n - 4) == ('.' | 'l' << 8 | 'u' << 16 | 'a' << 24);
|
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(
|
return firstnonnull(
|
||||||
GetContentTypeExt(path, n),
|
GetContentTypeExt(path, n),
|
||||||
firstnonnull(GetContentTypeExt(ZIP_CFILE_NAME(zbase + a->cf),
|
firstnonnull(GetContentTypeExt(ZIP_CFILE_NAME(zmap + a->cf),
|
||||||
ZIP_CFILE_NAMESIZE(zbase + a->cf)),
|
ZIP_CFILE_NAMESIZE(zmap + a->cf)),
|
||||||
a->istext ? "text/plain" : "application/octet-stream"));
|
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");
|
p = SetStatus(304, "Not Modified");
|
||||||
} else {
|
} else {
|
||||||
if (!a->file) {
|
if (!a->file) {
|
||||||
cpm.content = (char *)ZIP_LFILE_CONTENT(zbase + a->lf);
|
cpm.content = (char *)ZIP_LFILE_CONTENT(zmap + a->lf);
|
||||||
cpm.contentlength = GetZipCfileCompressedSize(zbase + a->cf);
|
cpm.contentlength = GetZipCfileCompressedSize(zmap + a->cf);
|
||||||
} else if ((p = OpenAsset(a))) {
|
} else if ((p = OpenAsset(a))) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -6164,7 +6154,7 @@ static char *ServeAsset(struct Asset *a, const char *path, size_t pathlen) {
|
||||||
LockInc(&shared->c.identityresponses);
|
LockInc(&shared->c.identityresponses);
|
||||||
DEBUGF("(zip) ServeAssetZipIdentity(%`'s)", ct);
|
DEBUGF("(zip) ServeAssetZipIdentity(%`'s)", ct);
|
||||||
if (Verify(cpm.content, cpm.contentlength,
|
if (Verify(cpm.content, cpm.contentlength,
|
||||||
ZIP_LFILE_CRC32(zbase + a->lf))) {
|
ZIP_LFILE_CRC32(zmap + a->lf))) {
|
||||||
p = SetStatus(200, "OK");
|
p = SetStatus(200, "OK");
|
||||||
} else {
|
} else {
|
||||||
return ServeError(500, "Internal Server Error");
|
return ServeError(500, "Internal Server Error");
|
||||||
|
|
Loading…
Reference in a new issue