mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Improve redbean plus code size optimizations
This change turns symbol table compression back on using Puff, which noticeably reduces the size of programs like redbean and Python. The redbean web server receives some minor API additions for controlling things like SSL in addition to filling gaps in the documentation.
This commit is contained in:
parent
425ff5dff0
commit
13ee75150c
58 changed files with 2077 additions and 589 deletions
|
@ -150,7 +150,7 @@ o/$(MODE)/examples/nesemu1.com: \
|
|||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/examples/.nesemu1/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/examples/.nesemu1/.symtab
|
||||
|
||||
o/$(MODE)/examples/nesemu1.o: QUOTA += -M512m
|
||||
|
|
|
@ -2,8 +2,20 @@
|
|||
#define COSMOPOLITAN_LIBC_BITS_LIKELY_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
#define LIKELY(expr) __builtin_expect(!!(expr), 1)
|
||||
#define UNLIKELY(expr) __builtin_expect(!!(expr), 0)
|
||||
#define LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
#if __GNUC__ + 0 >= 9 && !defined(__chibicc__)
|
||||
#define VERY_LIKELY(x) __builtin_expect_with_probability(!!(x), 1, 0.999)
|
||||
#else
|
||||
#define VERY_LIKELY(x) LIKELY(x)
|
||||
#endif
|
||||
|
||||
#if __GNUC__ + 0 >= 9 && !defined(__chibicc__)
|
||||
#define VERY_UNLIKELY(x) __builtin_expect_with_probability(!!(x), 0, 0.999)
|
||||
#else
|
||||
#define VERY_UNLIKELY(x) UNLIKELY(x)
|
||||
#endif
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_BITS_LIKELY_H_ */
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/syscall-nt.internal.h"
|
||||
|
@ -50,7 +51,7 @@ int execve(const char *prog, char *const argv[], char *const envp[]) {
|
|||
rc = efault();
|
||||
} else {
|
||||
#ifdef SYSDEBUG
|
||||
if (__strace > 0) {
|
||||
if (UNLIKELY(__strace > 0)) {
|
||||
kprintf(STRACE_PROLOGUE "execve(%#s, {", prog);
|
||||
for (i = 0; argv[i]; ++i) {
|
||||
if (i) kprintf(", ");
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
@ -82,7 +83,7 @@ int poll(struct pollfd *fds, size_t nfds, int timeout_ms) {
|
|||
}
|
||||
|
||||
#if defined(SYSDEBUG) && _POLLTRACE
|
||||
if (__strace > 0) {
|
||||
if (UNLIKELY(__strace > 0)) {
|
||||
kprintf(STRACE_PROLOGUE "poll(");
|
||||
if ((!IsAsan() && kisdangerous(fds)) ||
|
||||
(IsAsan() && !__asan_is_valid(fds, nfds * sizeof(struct pollfd)))) {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
|
@ -115,7 +116,7 @@ ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) {
|
|||
ssize_t rc;
|
||||
rc = Preadv(fd, iov, iovlen, off);
|
||||
#if defined(SYSDEBUG) && _DATATRACE
|
||||
if (__strace > 0) {
|
||||
if (UNLIKELY(__strace > 0)) {
|
||||
kprintf(STRACE_PROLOGUE "preadv(%d, [", fd);
|
||||
DescribeIov(iov, iovlen, rc != -1 ? rc : 0);
|
||||
kprintf("], %d, %'ld) → %'ld% m\n", iovlen, off, rc);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
|
@ -119,7 +120,7 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) {
|
|||
ssize_t rc;
|
||||
rc = Pwritev(fd, iov, iovlen, off);
|
||||
#if defined(SYSDEBUG) && _DATATRACE
|
||||
if (__strace > 0) {
|
||||
if (UNLIKELY(__strace > 0)) {
|
||||
kprintf(STRACE_PROLOGUE "pwritev(%d, ", fd);
|
||||
DescribeIov(iov, iovlen, rc != -1 ? rc : 0);
|
||||
kprintf(", %d, %'ld) → %'ld% m\n", iovlen, off, rc);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
|
@ -68,7 +69,7 @@ ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
|
|||
rc = einval();
|
||||
}
|
||||
#if defined(SYSDEBUG) && _DATATRACE
|
||||
if (__strace > 0) {
|
||||
if (UNLIKELY(__strace > 0)) {
|
||||
if (rc == -1 && errno == EFAULT) {
|
||||
STRACE("readv(%d, %p, %d) → %'zd% m", fd, iov, iovlen, rc);
|
||||
} else {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/rlimit.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
|
@ -19,7 +20,7 @@ COSMOPOLITAN_C_START_
|
|||
#ifdef SYSDEBUG
|
||||
#define STRACE(FMT, ...) \
|
||||
do { \
|
||||
if (__strace > 0) { \
|
||||
if (UNLIKELY(__strace > 0)) { \
|
||||
__stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
|
@ -75,7 +76,7 @@ ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
|
|||
}
|
||||
|
||||
#if defined(SYSDEBUG) && _DATATRACE
|
||||
if (__strace > 0) {
|
||||
if (UNLIKELY(__strace > 0)) {
|
||||
kprintf(STRACE_PROLOGUE "writev(%d, ", fd);
|
||||
DescribeIov(iov, iovlen, rc != -1 ? rc : 0);
|
||||
kprintf(", %d) → %'ld% m\n", iovlen, rc);
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern unsigned long long __kbirth;
|
||||
|
||||
void kprintf(const char *, ...);
|
||||
size_t ksnprintf(char *, size_t, const char *, ...);
|
||||
size_t kusnprintf(char *, size_t, const char *, ...);
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
STATIC_YOINK("_check_sigchld");
|
||||
|
||||
extern int64_t __wincrashearly;
|
||||
extern unsigned long long __kbirth;
|
||||
extern unsigned char __data_start[]; /* αpε */
|
||||
extern unsigned char __data_end[]; /* αpε */
|
||||
extern unsigned char __bss_start[]; /* αpε */
|
||||
|
|
|
@ -22,13 +22,14 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/undeflate.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/zip.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
#include "third_party/zlib/puff.h"
|
||||
|
||||
static int g_lock;
|
||||
hidden struct SymbolTable *__symtab; // for kprintf
|
||||
|
@ -56,9 +57,8 @@ static ssize_t FindSymtabInZip(struct Zipos *zipos) {
|
|||
* @note This code can't depend on dlmalloc()
|
||||
*/
|
||||
static struct SymbolTable *GetSymbolTableFromZip(struct Zipos *zipos) {
|
||||
ssize_t rc, cf, lf;
|
||||
size_t size, size2;
|
||||
struct DeflateState ds;
|
||||
ssize_t rc, cf, lf;
|
||||
struct SymbolTable *res = 0;
|
||||
if ((cf = FindSymtabInZip(zipos)) != -1) {
|
||||
lf = GetZipCfileOffset(zipos->map + cf);
|
||||
|
@ -69,17 +69,14 @@ static struct SymbolTable *GetSymbolTableFromZip(struct Zipos *zipos) {
|
|||
case kZipCompressionNone:
|
||||
memcpy(res, (void *)ZIP_LFILE_CONTENT(zipos->map + lf), size);
|
||||
break;
|
||||
#if 0
|
||||
// TODO(jart): fix me
|
||||
case kZipCompressionDeflate:
|
||||
rc = undeflate(res, size, (void *)ZIP_LFILE_CONTENT(zipos->map + lf),
|
||||
GetZipLfileCompressedSize(zipos->map + lf), &ds);
|
||||
if (rc == -1) {
|
||||
if (__inflate((void *)res, size,
|
||||
(void *)ZIP_LFILE_CONTENT(zipos->map + lf),
|
||||
GetZipLfileCompressedSize(zipos->map + lf))) {
|
||||
munmap(res, size2);
|
||||
res = 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
munmap(res, size2);
|
||||
res = 0;
|
||||
|
|
|
@ -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 2022 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,31 +16,48 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/http/escape.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "third_party/zlib/puff.h"
|
||||
#include "third_party/zlib/zlib.h"
|
||||
|
||||
// [user[:pass]@]host[:port]|reg_name dispatch
|
||||
// - 0 is -_.!~*'();&=+$,0-9A-Za-z
|
||||
// - 1 is everything else which needs uppercase hex %XX
|
||||
// note that '& can break html
|
||||
// note that '() can break css urls
|
||||
// note that unicode can still be wild
|
||||
// note that IPv6+ can't be encoded this way
|
||||
// note that user can look deceptively like host
|
||||
const char kEscapeAuthority[256] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
|
||||
1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 0x20
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, // 0x30
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 0x50
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, // 0x70
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xe0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xf0
|
||||
};
|
||||
/**
|
||||
* Decompresses raw deflate data.
|
||||
*
|
||||
* This uses puff by default since it has a 2kb footprint. If zlib
|
||||
* proper is linked, then we favor that instead, since it's faster.
|
||||
*
|
||||
* @param outsize needs to be known ahead of time by some other means
|
||||
* @return 0 on success or nonzero on failure
|
||||
*/
|
||||
int __inflate(void *out, size_t outsize, const void *in, size_t insize) {
|
||||
int rc;
|
||||
z_stream zs;
|
||||
if (weaken(inflateInit2) && weaken(inflate) && weaken(inflateEnd)) {
|
||||
zs.next_in = in;
|
||||
zs.avail_in = insize;
|
||||
zs.total_in = insize;
|
||||
zs.next_out = out;
|
||||
zs.avail_out = outsize;
|
||||
zs.total_out = outsize;
|
||||
zs.zalloc = Z_NULL;
|
||||
zs.zfree = Z_NULL;
|
||||
if ((rc = weaken(inflateInit2)(&zs, -MAX_WBITS)) == Z_OK &&
|
||||
(rc = weaken(inflate)(&zs, Z_FINISH)) == Z_STREAM_END &&
|
||||
(rc = weaken(inflateEnd)(&zs)) == Z_OK) {
|
||||
rc = 0;
|
||||
} else if (rc == Z_OK) {
|
||||
rc = Z_STREAM_END; // coerce to nonzero
|
||||
} else {
|
||||
rc = rc;
|
||||
}
|
||||
} else {
|
||||
rc = puff(out, &outsize, in, &insize);
|
||||
}
|
||||
STRACE("inflate([%#.*hhs%s], %'zu, %#.*hhs%s, %'zu) → %d", MIN(40, outsize),
|
||||
out, outsize > 40 ? "..." : "", outsize, MIN(40, insize), in,
|
||||
insize > 40 ? "..." : "", insize, rc);
|
||||
return rc;
|
||||
}
|
|
@ -38,6 +38,7 @@ Elf64_Ehdr *MapElfRead(const char *, struct MappedFile *) hidden;
|
|||
int GetDosEnviron(const char16_t *, char *, size_t, char **, size_t);
|
||||
bool __intercept_flag(int *, char *[], const char *);
|
||||
int sys_mprotect_nt(void *, size_t, int) hidden;
|
||||
int __inflate(void *, size_t, const void *, size_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -176,14 +176,14 @@ static noasan void *MapMemory(void *addr, size_t size, int prot, int flags,
|
|||
int fd, int64_t off, int f, int x, int n) {
|
||||
struct DirectMap dm;
|
||||
dm = sys_mmap(addr, size, prot, f, fd, off);
|
||||
if (UNLIKELY(dm.addr == MAP_FAILED)) {
|
||||
if (VERY_UNLIKELY(dm.addr == MAP_FAILED)) {
|
||||
if (IsWindows() && (flags & MAP_FIXED)) {
|
||||
OnUnrecoverableMmapError(
|
||||
"can't recover from MAP_FIXED errors on Windows");
|
||||
}
|
||||
return MAP_FAILED;
|
||||
}
|
||||
if (UNLIKELY(dm.addr != addr)) {
|
||||
if (VERY_UNLIKELY(dm.addr != addr)) {
|
||||
OnUnrecoverableMmapError("KERNEL DIDN'T RESPECT MAP_FIXED");
|
||||
}
|
||||
return FinishMemory(addr, size, prot, flags, fd, off, f, x, n, dm);
|
||||
|
@ -248,42 +248,42 @@ static noasan inline void *Mmap(void *addr, size_t size, int prot, int flags,
|
|||
bool needguard, clashes;
|
||||
size_t virtualused, virtualneed;
|
||||
|
||||
if (UNLIKELY(!size)) {
|
||||
if (VERY_UNLIKELY(!size)) {
|
||||
STRACE("size=0");
|
||||
return VIP(einval());
|
||||
}
|
||||
|
||||
if (UNLIKELY(!IsLegalPointer(p))) {
|
||||
if (VERY_UNLIKELY(!IsLegalPointer(p))) {
|
||||
STRACE("p isn't 48-bit");
|
||||
return VIP(einval());
|
||||
}
|
||||
|
||||
if (UNLIKELY(!ALIGNED(p))) {
|
||||
if (VERY_UNLIKELY(!ALIGNED(p))) {
|
||||
STRACE("p isn't 64kb aligned");
|
||||
return VIP(einval());
|
||||
}
|
||||
|
||||
if (UNLIKELY(fd < -1)) {
|
||||
if (VERY_UNLIKELY(fd < -1)) {
|
||||
STRACE("mmap(%.12p, %'zu, fd=%d) EBADF", p, size, fd);
|
||||
return VIP(ebadf());
|
||||
}
|
||||
|
||||
if (UNLIKELY(!((fd != -1) ^ !!(flags & MAP_ANONYMOUS)))) {
|
||||
if (VERY_UNLIKELY(!((fd != -1) ^ !!(flags & MAP_ANONYMOUS)))) {
|
||||
STRACE("fd anonymous mismatch");
|
||||
return VIP(einval());
|
||||
}
|
||||
|
||||
if (UNLIKELY(!(!!(flags & MAP_PRIVATE) ^ !!(flags & MAP_SHARED)))) {
|
||||
if (VERY_UNLIKELY(!(!!(flags & MAP_PRIVATE) ^ !!(flags & MAP_SHARED)))) {
|
||||
STRACE("MAP_SHARED ^ MAP_PRIVATE");
|
||||
return VIP(einval());
|
||||
}
|
||||
|
||||
if (UNLIKELY(off < 0)) {
|
||||
if (VERY_UNLIKELY(off < 0)) {
|
||||
STRACE("neg off");
|
||||
return VIP(einval());
|
||||
}
|
||||
|
||||
if (UNLIKELY(!ALIGNED(off))) {
|
||||
if (VERY_UNLIKELY(!ALIGNED(off))) {
|
||||
STRACE("p isn't 64kb aligned");
|
||||
return VIP(einval());
|
||||
}
|
||||
|
@ -298,12 +298,12 @@ static noasan inline void *Mmap(void *addr, size_t size, int prot, int flags,
|
|||
return VIP(einval());
|
||||
}
|
||||
|
||||
if (UNLIKELY(!IsLegalSize(size))) {
|
||||
if (VERY_UNLIKELY(!IsLegalSize(size))) {
|
||||
STRACE("size isn't 48-bit");
|
||||
return VIP(einval());
|
||||
}
|
||||
|
||||
if (UNLIKELY(INT64_MAX - size < off)) {
|
||||
if (VERY_UNLIKELY(INT64_MAX - size < off)) {
|
||||
STRACE("too large");
|
||||
return VIP(einval());
|
||||
}
|
||||
|
|
|
@ -127,23 +127,23 @@ static noasan int Munmap(char *p, size_t n) {
|
|||
intptr_t a, b, x, y;
|
||||
assert(!__vforked);
|
||||
if (UNLIKELY(!n)) {
|
||||
STRACE("munmap(%.12p, %'zu) EINVAL (n=0)", p, n);
|
||||
STRACE("n=0");
|
||||
return einval();
|
||||
}
|
||||
if (UNLIKELY(!IsLegalSize(n))) {
|
||||
STRACE("munmap(%.12p, %'zu) EINVAL (n isn't 48-bit)", p, n);
|
||||
STRACE("n isn't 48-bit");
|
||||
return einval();
|
||||
}
|
||||
if (UNLIKELY(!IsLegalPointer(p))) {
|
||||
STRACE("munmap(%.12p, %'zu) EINVAL (p isn't 48-bit)", p, n);
|
||||
STRACE("p isn't 48-bit");
|
||||
return einval();
|
||||
}
|
||||
if (UNLIKELY(!IsLegalPointer(p + (n - 1)))) {
|
||||
STRACE("munmap(%.12p, %'zu) EINVAL (p+(n-1) isn't 48-bit)", p, n);
|
||||
STRACE("p+(n-1) isn't 48-bit");
|
||||
return einval();
|
||||
}
|
||||
if (UNLIKELY(!ALIGNED(p))) {
|
||||
STRACE("munmap(%.12p, %'zu) EINVAL (p isn't 64kb aligned)", p, n);
|
||||
STRACE("p isn't 64kb aligned");
|
||||
return einval();
|
||||
}
|
||||
MunmapImpl(p, n);
|
||||
|
|
|
@ -44,6 +44,7 @@ LIBC_RUNTIME_A_DIRECTDEPS = \
|
|||
LIBC_STUBS \
|
||||
LIBC_SYSV \
|
||||
LIBC_SYSV_CALLS \
|
||||
THIRD_PARTY_ZLIB \
|
||||
THIRD_PARTY_XED
|
||||
|
||||
LIBC_RUNTIME_A_DEPS := \
|
||||
|
|
|
@ -30,10 +30,10 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/crc32.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/undeflate.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
@ -43,47 +43,8 @@
|
|||
#include "libc/zipos/zipos.internal.h"
|
||||
#include "third_party/zlib/zlib.h"
|
||||
|
||||
static int __zipos_inflate_fast(struct ZiposHandle *h, uint8_t *data,
|
||||
size_t size) {
|
||||
int rc;
|
||||
z_stream zs;
|
||||
zs.opaque = &h;
|
||||
zs.next_in = data;
|
||||
zs.avail_in = size;
|
||||
zs.total_in = size;
|
||||
zs.next_out = h->freeme;
|
||||
zs.avail_out = h->size;
|
||||
zs.total_out = h->size;
|
||||
zs.zfree = Z_NULL;
|
||||
zs.zalloc = Z_NULL;
|
||||
if (inflateInit2(&zs, -MAX_WBITS) == Z_OK) {
|
||||
switch (inflate(&zs, Z_NO_FLUSH)) {
|
||||
case Z_STREAM_END:
|
||||
rc = 0;
|
||||
break;
|
||||
case Z_MEM_ERROR:
|
||||
rc = enomem();
|
||||
break;
|
||||
case Z_DATA_ERROR:
|
||||
rc = eio();
|
||||
break;
|
||||
case Z_NEED_DICT:
|
||||
rc = enotsup(); /* TODO(jart): Z_NEED_DICT */
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
inflateEnd(&zs);
|
||||
} else {
|
||||
rc = enomem();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __zipos_inflate_tiny(struct ZiposHandle *h, uint8_t *data,
|
||||
size_t size) {
|
||||
struct DeflateState ds;
|
||||
return undeflate(h->freeme, h->size, data, size, &ds) != -1 ? 0 : eio();
|
||||
static int __zipos_inflate(struct ZiposHandle *h, uint8_t *data, size_t size) {
|
||||
return !__inflate(h->freeme, h->size, data, size) ? 0 : eio();
|
||||
}
|
||||
|
||||
static int __zipos_load(struct Zipos *zipos, size_t cf, unsigned flags,
|
||||
|
@ -108,12 +69,7 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, unsigned flags,
|
|||
if ((h->freeme = malloc(h->size))) {
|
||||
data = ZIP_LFILE_CONTENT(zipos->map + lf);
|
||||
size = GetZipLfileCompressedSize(zipos->map + lf);
|
||||
if (IsTiny()) {
|
||||
rc = __zipos_inflate_tiny(h, data, size);
|
||||
} else {
|
||||
rc = __zipos_inflate_fast(h, data, size);
|
||||
}
|
||||
if (rc != -1) {
|
||||
if ((rc = __zipos_inflate(h, data, size)) != -1) {
|
||||
h->mem = h->freeme;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,13 @@ NET_HTTP = $(NET_HTTP_A_DEPS) $(NET_HTTP_A)
|
|||
NET_HTTP_A = o/$(MODE)/net/http/http.a
|
||||
NET_HTTP_A_FILES := $(wildcard net/http/*)
|
||||
NET_HTTP_A_HDRS = $(filter %.h,$(NET_HTTP_A_FILES))
|
||||
NET_HTTP_A_SRCS = $(filter %.c,$(NET_HTTP_A_FILES))
|
||||
NET_HTTP_A_INCS := $(filter %.inc,$(NET_HTTP_A_FILES))
|
||||
NET_HTTP_A_OBJS = $(NET_HTTP_A_SRCS:%.c=o/$(MODE)/%.o)
|
||||
NET_HTTP_A_SRCS_C = $(filter %.c,$(NET_HTTP_A_FILES))
|
||||
NET_HTTP_A_SRCS_S = $(filter %.S,$(NET_HTTP_A_FILES))
|
||||
NET_HTTP_A_SRCS = $(NET_HTTP_A_SRCS_S) $(NET_HTTP_A_SRCS_C)
|
||||
NET_HTTP_A_OBJS_C = $(NET_HTTP_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
NET_HTTP_A_OBJS_S = $(NET_HTTP_A_SRCS_S:%.S=o/$(MODE)/%.o)
|
||||
NET_HTTP_A_OBJS = $(NET_HTTP_A_OBJS_S) $(NET_HTTP_A_OBJS_C)
|
||||
|
||||
NET_HTTP_A_CHECKS = \
|
||||
$(NET_HTTP_A).pkg \
|
||||
|
|
83
net/http/kescapeauthority.S
Normal file
83
net/http/kescapeauthority.S
Normal file
|
@ -0,0 +1,83 @@
|
|||
#include "libc/macros.internal.h"
|
||||
|
||||
// generated by:
|
||||
// o//tool/build/xlat.com -DUL '_.!~*'"'"'();&=+$,-' -iskEscapeAuthority
|
||||
//
|
||||
// present absent
|
||||
// ──────────────── ────────────────
|
||||
// ∅☺☻♥♦♣♠•◘○◙♂♀♪♫☼ 0x00
|
||||
// ►◄↕‼¶§▬↨↑↓→←∟↔▲▼ 0x10
|
||||
// ␠ “# % / ! $ &‘()*+,-. 0x20
|
||||
// : < >⁇ 0123456789 ; = 0x30
|
||||
// @ ABCDEFGHIJKLMNO 0x40
|
||||
// [⭝]^ PQRSTUVWXYZ _ 0x50
|
||||
// ` abcdefghijklmno 0x60
|
||||
// {|} ⌂ pqrstuvwxyz ~ 0x70
|
||||
// ÇüéâäàåçêëèïîìÄÅ 0x80
|
||||
// ÉæÆôöòûùÿÖÜ¢£¥€ƒ 0x90
|
||||
// áíóúñѪº¿⌐¬½¼¡«» 0xa0
|
||||
// ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐ 0xb0
|
||||
// └┴┬├─┼╞╟╚╔╩╦╠═╬╧ 0xc0
|
||||
// ╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ 0xd0
|
||||
// αßΓπΣσμτΦΘΩδ∞φε∩ 0xe0
|
||||
// ≡±≥≤⌠⌡÷≈°∙×√ⁿ²■λ 0xf0
|
||||
//
|
||||
// const char kEscapeAuthority[256] = {
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
|
||||
// 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 0x20
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, // 0x30
|
||||
// 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 0x50
|
||||
// 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, // 0x70
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xe0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xf0
|
||||
// };
|
||||
|
||||
.initbss 300,_init_kEscapeAuthority
|
||||
kEscapeAuthority:
|
||||
.zero 256
|
||||
.endobj kEscapeAuthority,globl
|
||||
.previous
|
||||
|
||||
.initro 300,_init_kEscapeAuthority
|
||||
kEscapeAuthority.rom:
|
||||
.byte 33,1 # 00-20 ∅-␠
|
||||
.byte 1,0 # 21-21 !-!
|
||||
.byte 2,1 # 22-23 “-#
|
||||
.byte 1,0 # 24-24 §-§
|
||||
.byte 1,1 # 25-25 %-%
|
||||
.byte 9,0 # 26-2e &-.
|
||||
.byte 1,1 # 2f-2f /-/
|
||||
.byte 10,0 # 30-39 0-9
|
||||
.byte 1,1 # 3a-3a :-:
|
||||
.byte 1,0 # 3b-3b ;-;
|
||||
.byte 1,1 # 3c-3c <-<
|
||||
.byte 1,0 # 3d-3d =-=
|
||||
.byte 3,1 # 3e-40 >-@
|
||||
.byte 26,0 # 41-5a A-Z
|
||||
.byte 4,1 # 5b-5e [-^
|
||||
.byte 1,0 # 5f-5f _-_
|
||||
.byte 1,1 # 60-60 `-`
|
||||
.byte 26,0 # 61-7a a-z
|
||||
.byte 3,1 # 7b-7d {-}
|
||||
.byte 1,0 # 7e-7e ~-~
|
||||
.byte 129,1 # 7f-ff ⌂-λ
|
||||
.byte 0,0 # terminator
|
||||
.byte 0,0 # padding
|
||||
.byte 0,0 # padding
|
||||
.endobj kEscapeAuthority.rom,globl
|
||||
|
||||
.init.start 300,_init_kEscapeAuthority
|
||||
call rldecode
|
||||
lodsl
|
||||
.init.end 300,_init_kEscapeAuthority
|
||||
|
||||
// 54 bytes total (21% original size)
|
79
net/http/kescapefragment.S
Normal file
79
net/http/kescapefragment.S
Normal file
|
@ -0,0 +1,79 @@
|
|||
#include "libc/macros.internal.h"
|
||||
|
||||
// generated by:
|
||||
// o//tool/build/xlat.com -DUL '/?.~_@:!$&'"'"'()*+,;=-' -iskEscapeFragment
|
||||
//
|
||||
// present absent
|
||||
// ──────────────── ────────────────
|
||||
// ∅☺☻♥♦♣♠•◘○◙♂♀♪♫☼ 0x00
|
||||
// ►◄↕‼¶§▬↨↑↓→←∟↔▲▼ 0x10
|
||||
// ␠ “# % ! § &‘()*+,-./ 0x20
|
||||
// < > 0123456789:; = ⁇ 0x30
|
||||
// @ABCDEFGHIJKLMNO 0x40
|
||||
// [⭝]^ PQRSTUVWXYZ _ 0x50
|
||||
// ` abcdefghijklmno 0x60
|
||||
// {|} ⌂ pqrstuvwxyz ~ 0x70
|
||||
// ÇüéâäàåçêëèïîìÄÅ 0x80
|
||||
// ÉæÆôöòûùÿÖÜ¢£¥€ƒ 0x90
|
||||
// áíóúñѪº¿⌐¬½¼¡«» 0xa0
|
||||
// ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐ 0xb0
|
||||
// └┴┬├─┼╞╟╚╔╩╦╠═╬╧ 0xc0
|
||||
// ╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ 0xd0
|
||||
// αßΓπΣσμτΦΘΩδ∞φε∩ 0xe0
|
||||
// ≡±≥≤⌠⌡÷≈°∙×√ⁿ²■λ 0xf0
|
||||
//
|
||||
// const char kEscapeFragment[256] = {
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
|
||||
// 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, // 0x30
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 0x50
|
||||
// 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, // 0x70
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xe0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xf0
|
||||
// };
|
||||
|
||||
.initbss 300,_init_kEscapeFragment
|
||||
kEscapeFragment:
|
||||
.zero 256
|
||||
.endobj kEscapeFragment,globl
|
||||
.previous
|
||||
|
||||
.initro 300,_init_kEscapeFragment
|
||||
kEscapeFragment.rom:
|
||||
.byte 33,1 # 00-20 ∅-␠
|
||||
.byte 1,0 # 21-21 !-!
|
||||
.byte 2,1 # 22-23 “-#
|
||||
.byte 1,0 # 24-24 §-§
|
||||
.byte 1,1 # 25-25 %-%
|
||||
.byte 22,0 # 26-3b &-;
|
||||
.byte 1,1 # 3c-3c <-<
|
||||
.byte 1,0 # 3d-3d =-=
|
||||
.byte 1,1 # 3e-3e >->
|
||||
.byte 28,0 # 3f-5a ⁇-Z
|
||||
.byte 4,1 # 5b-5e [-^
|
||||
.byte 1,0 # 5f-5f _-_
|
||||
.byte 1,1 # 60-60 `-`
|
||||
.byte 26,0 # 61-7a a-z
|
||||
.byte 3,1 # 7b-7d {-}
|
||||
.byte 1,0 # 7e-7e ~-~
|
||||
.byte 129,1 # 7f-ff ⌂-λ
|
||||
.byte 0,0 # terminator
|
||||
.byte 0,0 # padding
|
||||
.byte 0,0 # padding
|
||||
.endobj kEscapeFragment.rom,globl
|
||||
|
||||
.init.start 300,_init_kEscapeFragment
|
||||
call rldecode
|
||||
lodsl
|
||||
.init.end 300,_init_kEscapeFragment
|
||||
|
||||
// 46 bytes total (18% original size)
|
|
@ -1,44 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/http/escape.h"
|
||||
|
||||
// url fragment dispatch
|
||||
// - 0 is -/?.~_@:!$&'()*+,;=0-9A-Za-z
|
||||
// - 1 is everything else which needs uppercase hex %XX
|
||||
// note that '& can break html
|
||||
// note that '() can break css urls
|
||||
// note that unicode can still be wild
|
||||
const char kEscapeFragment[256] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
|
||||
1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, // 0x30
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 0x50
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, // 0x70
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xe0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xf0
|
||||
};
|
78
net/http/kescapeip.S
Normal file
78
net/http/kescapeip.S
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include "libc/macros.internal.h"
|
||||
|
||||
// generated by:
|
||||
// o//tool/build/xlat.com -DUL '_-.!~*'"'"'();&=+$,:' -iskEscapeIp
|
||||
//
|
||||
// present absent
|
||||
// ──────────────── ────────────────
|
||||
// ∅☺☻♥♦♣♠•◘○◙♂♀♪♫☼ 0x00
|
||||
// ►◄↕‼¶§▬↨↑↓→←∟↔▲▼ 0x10
|
||||
// ␠ “# % / ! § &‘()*+,-. 0x20
|
||||
// < >⁇ 0123456789:; = 0x30
|
||||
// @ ABCDEFGHIJKLMNO 0x40
|
||||
// [⭝]^ PQRSTUVWXYZ _ 0x50
|
||||
// ` abcdefghijklmno 0x60
|
||||
// {|} ⌂ pqrstuvwxyz ~ 0x70
|
||||
// ÇüéâäàåçêëèïîìÄÅ 0x80
|
||||
// ÉæÆôöòûùÿÖÜ¢£¥€ƒ 0x90
|
||||
// áíóúñѪº¿⌐¬½¼¡«» 0xa0
|
||||
// ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐ 0xb0
|
||||
// └┴┬├─┼╞╟╚╔╩╦╠═╬╧ 0xc0
|
||||
// ╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ 0xd0
|
||||
// αßΓπΣσμτΦΘΩδ∞φε∩ 0xe0
|
||||
// ≡±≥≤⌠⌡÷≈°∙×√ⁿ²■λ 0xf0
|
||||
//
|
||||
// const char kEscapeIp[256] = {
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
|
||||
// 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 0x20
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, // 0x30
|
||||
// 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 0x50
|
||||
// 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, // 0x70
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xe0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xf0
|
||||
// };
|
||||
|
||||
.initbss 300,_init_kEscapeIp
|
||||
kEscapeIp:
|
||||
.zero 256
|
||||
.endobj kEscapeIp,globl
|
||||
.previous
|
||||
|
||||
.initro 300,_init_kEscapeIp
|
||||
kEscapeIp.rom:
|
||||
.byte 33,1 # 00-20 ∅-␠
|
||||
.byte 1,0 # 21-21 !-!
|
||||
.byte 2,1 # 22-23 “-#
|
||||
.byte 1,0 # 24-24 §-§
|
||||
.byte 1,1 # 25-25 %-%
|
||||
.byte 9,0 # 26-2e &-.
|
||||
.byte 1,1 # 2f-2f /-/
|
||||
.byte 12,0 # 30-3b 0-;
|
||||
.byte 1,1 # 3c-3c <-<
|
||||
.byte 1,0 # 3d-3d =-=
|
||||
.byte 3,1 # 3e-40 >-@
|
||||
.byte 26,0 # 41-5a A-Z
|
||||
.byte 4,1 # 5b-5e [-^
|
||||
.byte 1,0 # 5f-5f _-_
|
||||
.byte 1,1 # 60-60 `-`
|
||||
.byte 26,0 # 61-7a a-z
|
||||
.byte 3,1 # 7b-7d {-}
|
||||
.byte 1,0 # 7e-7e ~-~
|
||||
.byte 129,1 # 7f-ff ⌂-λ
|
||||
.byte 0,0 # terminator
|
||||
.endobj kEscapeIp.rom,globl
|
||||
|
||||
.init.start 300,_init_kEscapeIp
|
||||
call rldecode
|
||||
.init.end 300,_init_kEscapeIp
|
||||
|
||||
// 45 bytes total (18% original size)
|
|
@ -1,44 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/http/escape.h"
|
||||
|
||||
// Square Bracket IP-literal dispatch
|
||||
// - 0 is -_.!~*'();&=+$,0-9A-Za-z:
|
||||
// - 1 shouldn't be there; exceptions exist; escape it
|
||||
// same as kEscapeAuthority but with colon
|
||||
// note that '& can break html
|
||||
// note that '() can break css urls
|
||||
const char kEscapeIp[256] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
|
||||
1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 0x20
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, // 0x30
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 0x50
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, // 0x70
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xe0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xf0
|
||||
};
|
75
net/http/kescapeparam.S
Normal file
75
net/http/kescapeparam.S
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include "libc/macros.internal.h"
|
||||
|
||||
// generated by:
|
||||
// o//tool/build/xlat.com -DUL '.-*_' -iskEscapeParam
|
||||
//
|
||||
// present absent
|
||||
// ──────────────── ────────────────
|
||||
// ∅☺☻♥♦♣♠•◘○◙♂♀♪♫☼ 0x00
|
||||
// ►◄↕‼¶§▬↨↑↓→←∟↔▲▼ 0x10
|
||||
// ␠!“#§%&‘() +, / * -. 0x20
|
||||
// :;<=>⁇ 0123456789 0x30
|
||||
// @ ABCDEFGHIJKLMNO 0x40
|
||||
// [⭝]^ PQRSTUVWXYZ _ 0x50
|
||||
// ` abcdefghijklmno 0x60
|
||||
// {|}~⌂ pqrstuvwxyz 0x70
|
||||
// ÇüéâäàåçêëèïîìÄÅ 0x80
|
||||
// ÉæÆôöòûùÿÖÜ¢£¥€ƒ 0x90
|
||||
// áíóúñѪº¿⌐¬½¼¡«» 0xa0
|
||||
// ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐ 0xb0
|
||||
// └┴┬├─┼╞╟╚╔╩╦╠═╬╧ 0xc0
|
||||
// ╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ 0xd0
|
||||
// αßΓπΣσμτΦΘΩδ∞φε∩ 0xe0
|
||||
// ≡±≥≤⌠⌡÷≈°∙×√ⁿ²■λ 0xf0
|
||||
//
|
||||
// const char kEscapeParam[256] = {
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, // 0x20
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, // 0x30
|
||||
// 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 0x50
|
||||
// 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, // 0x70
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xe0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xf0
|
||||
// };
|
||||
|
||||
.initbss 300,_init_kEscapeParam
|
||||
kEscapeParam:
|
||||
.zero 256
|
||||
.endobj kEscapeParam,globl
|
||||
.previous
|
||||
|
||||
.initro 300,_init_kEscapeParam
|
||||
kEscapeParam.rom:
|
||||
.byte 42,1 # 00-29 ∅-)
|
||||
.byte 1,0 # 2a-2a *-*
|
||||
.byte 2,1 # 2b-2c +-,
|
||||
.byte 2,0 # 2d-2e --.
|
||||
.byte 1,1 # 2f-2f /-/
|
||||
.byte 10,0 # 30-39 0-9
|
||||
.byte 7,1 # 3a-40 :-@
|
||||
.byte 26,0 # 41-5a A-Z
|
||||
.byte 4,1 # 5b-5e [-^
|
||||
.byte 1,0 # 5f-5f _-_
|
||||
.byte 1,1 # 60-60 `-`
|
||||
.byte 26,0 # 61-7a a-z
|
||||
.byte 133,1 # 7b-ff {-λ
|
||||
.byte 0,0 # terminator
|
||||
.byte 0,0 # padding
|
||||
.byte 0,0 # padding
|
||||
.endobj kEscapeParam.rom,globl
|
||||
|
||||
.init.start 300,_init_kEscapeParam
|
||||
call rldecode
|
||||
lodsl
|
||||
.init.end 300,_init_kEscapeParam
|
||||
|
||||
// 38 bytes total (15% original size)
|
|
@ -1,42 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/http/escape.h"
|
||||
|
||||
// url query/form name/parameter dispatch
|
||||
// - 0 is -.*_0-9A-Za-z
|
||||
// - 1 is everything else which needs uppercase hex %XX
|
||||
// note that unicode can still be wild
|
||||
const char kEscapeParam[256] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, // 0x20
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, // 0x30
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 0x50
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, // 0x70
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xe0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xf0
|
||||
};
|
79
net/http/kescapepath.S
Normal file
79
net/http/kescapepath.S
Normal file
|
@ -0,0 +1,79 @@
|
|||
#include "libc/macros.internal.h"
|
||||
|
||||
// generated by:
|
||||
// o//tool/build/xlat.com -DUL '.-~_@:!$&'"'"'()*+,;=/' -iskEscapePath
|
||||
//
|
||||
// present absent
|
||||
// ──────────────── ────────────────
|
||||
// ∅☺☻♥♦♣♠•◘○◙♂♀♪♫☼ 0x00
|
||||
// ►◄↕‼¶§▬↨↑↓→←∟↔▲▼ 0x10
|
||||
// ␠ “# % ! § &‘()*+,-./ 0x20
|
||||
// < >⁇ 0123456789:; = 0x30
|
||||
// @ABCDEFGHIJKLMNO 0x40
|
||||
// [⭝]^ PQRSTUVWXYZ _ 0x50
|
||||
// ` abcdefghijklmno 0x60
|
||||
// {|} ⌂ pqrstuvwxyz ~ 0x70
|
||||
// ÇüéâäàåçêëèïîìÄÅ 0x80
|
||||
// ÉæÆôöòûùÿÖÜ¢£¥€ƒ 0x90
|
||||
// áíóúñѪº¿⌐¬½¼¡«» 0xa0
|
||||
// ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐ 0xb0
|
||||
// └┴┬├─┼╞╟╚╔╩╦╠═╬╧ 0xc0
|
||||
// ╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ 0xd0
|
||||
// αßΓπΣσμτΦΘΩδ∞φε∩ 0xe0
|
||||
// ≡±≥≤⌠⌡÷≈°∙×√ⁿ²■λ 0xf0
|
||||
//
|
||||
// const char kEscapePath[256] = {
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
|
||||
// 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, // 0x30
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 0x50
|
||||
// 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, // 0x70
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xe0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xf0
|
||||
// };
|
||||
|
||||
.initbss 300,_init_kEscapePath
|
||||
kEscapePath:
|
||||
.zero 256
|
||||
.endobj kEscapePath,globl
|
||||
.previous
|
||||
|
||||
.initro 300,_init_kEscapePath
|
||||
kEscapePath.rom:
|
||||
.byte 33,1 # 00-20 ∅-␠
|
||||
.byte 1,0 # 21-21 !-!
|
||||
.byte 2,1 # 22-23 “-#
|
||||
.byte 1,0 # 24-24 §-§
|
||||
.byte 1,1 # 25-25 %-%
|
||||
.byte 22,0 # 26-3b &-;
|
||||
.byte 1,1 # 3c-3c <-<
|
||||
.byte 1,0 # 3d-3d =-=
|
||||
.byte 2,1 # 3e-3f >-⁇
|
||||
.byte 27,0 # 40-5a @-Z
|
||||
.byte 4,1 # 5b-5e [-^
|
||||
.byte 1,0 # 5f-5f _-_
|
||||
.byte 1,1 # 60-60 `-`
|
||||
.byte 26,0 # 61-7a a-z
|
||||
.byte 3,1 # 7b-7d {-}
|
||||
.byte 1,0 # 7e-7e ~-~
|
||||
.byte 129,1 # 7f-ff ⌂-λ
|
||||
.byte 0,0 # terminator
|
||||
.byte 0,0 # padding
|
||||
.byte 0,0 # padding
|
||||
.endobj kEscapePath.rom,globl
|
||||
|
||||
.init.start 300,_init_kEscapePath
|
||||
call rldecode
|
||||
lodsl
|
||||
.init.end 300,_init_kEscapePath
|
||||
|
||||
// 46 bytes total (18% original size)
|
|
@ -1,44 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/http/escape.h"
|
||||
|
||||
// url path dispatch
|
||||
// - 0 is -.~_@:!$&'()*+,;=0-9A-Za-z/
|
||||
// - 1 is everything else which needs uppercase hex %XX
|
||||
// note that '& can break html
|
||||
// note that '() can break css urls
|
||||
// note that unicode can still be wild
|
||||
const char kEscapePath[256] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
|
||||
1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, // 0x30
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 0x50
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, // 0x70
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xe0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xf0
|
||||
};
|
78
net/http/kescapesegment.S
Normal file
78
net/http/kescapesegment.S
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include "libc/macros.internal.h"
|
||||
|
||||
// generated by:
|
||||
// o//tool/build/xlat.com -DUL '.-~_@:!$&'"'"'()*+,;=' -iskEscapeSegment
|
||||
//
|
||||
// present absent
|
||||
// ──────────────── ────────────────
|
||||
// ∅☺☻♥♦♣♠•◘○◙♂♀♪♫☼ 0x00
|
||||
// ►◄↕‼¶§▬↨↑↓→←∟↔▲▼ 0x10
|
||||
// ␠ “# % / ! § &‘()*+,-. 0x20
|
||||
// < >⁇ 0123456789:; = 0x30
|
||||
// @ABCDEFGHIJKLMNO 0x40
|
||||
// [⭝]^ PQRSTUVWXYZ _ 0x50
|
||||
// ` abcdefghijklmno 0x60
|
||||
// {|} ⌂ pqrstuvwxyz ~ 0x70
|
||||
// ÇüéâäàåçêëèïîìÄÅ 0x80
|
||||
// ÉæÆôöòûùÿÖÜ¢£¥€ƒ 0x90
|
||||
// áíóúñѪº¿⌐¬½¼¡«» 0xa0
|
||||
// ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐ 0xb0
|
||||
// └┴┬├─┼╞╟╚╔╩╦╠═╬╧ 0xc0
|
||||
// ╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ 0xd0
|
||||
// αßΓπΣσμτΦΘΩδ∞φε∩ 0xe0
|
||||
// ≡±≥≤⌠⌡÷≈°∙×√ⁿ²■λ 0xf0
|
||||
//
|
||||
// const char kEscapeSegment[256] = {
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
|
||||
// 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 0x20
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, // 0x30
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 0x50
|
||||
// 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, // 0x70
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xe0
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xf0
|
||||
// };
|
||||
|
||||
.initbss 300,_init_kEscapeSegment
|
||||
kEscapeSegment:
|
||||
.zero 256
|
||||
.endobj kEscapeSegment,globl
|
||||
.previous
|
||||
|
||||
.initro 300,_init_kEscapeSegment
|
||||
kEscapeSegment.rom:
|
||||
.byte 33,1 # 00-20 ∅-␠
|
||||
.byte 1,0 # 21-21 !-!
|
||||
.byte 2,1 # 22-23 “-#
|
||||
.byte 1,0 # 24-24 §-§
|
||||
.byte 1,1 # 25-25 %-%
|
||||
.byte 9,0 # 26-2e &-.
|
||||
.byte 1,1 # 2f-2f /-/
|
||||
.byte 12,0 # 30-3b 0-;
|
||||
.byte 1,1 # 3c-3c <-<
|
||||
.byte 1,0 # 3d-3d =-=
|
||||
.byte 2,1 # 3e-3f >-⁇
|
||||
.byte 27,0 # 40-5a @-Z
|
||||
.byte 4,1 # 5b-5e [-^
|
||||
.byte 1,0 # 5f-5f _-_
|
||||
.byte 1,1 # 60-60 `-`
|
||||
.byte 26,0 # 61-7a a-z
|
||||
.byte 3,1 # 7b-7d {-}
|
||||
.byte 1,0 # 7e-7e ~-~
|
||||
.byte 129,1 # 7f-ff ⌂-λ
|
||||
.byte 0,0 # terminator
|
||||
.endobj kEscapeSegment.rom,globl
|
||||
|
||||
.init.start 300,_init_kEscapeSegment
|
||||
call rldecode
|
||||
.init.end 300,_init_kEscapeSegment
|
||||
|
||||
// 45 bytes total (18% original size)
|
|
@ -1,44 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/http/escape.h"
|
||||
|
||||
// url path segment dispatch
|
||||
// - 0 is -.~_@:!$&'()*+,;=0-9A-Za-z
|
||||
// - 1 is everything else which needs uppercase hex %XX
|
||||
// note that '& can break html
|
||||
// note that '() can break css urls
|
||||
// note that unicode can still be wild
|
||||
const char kEscapeSegment[256] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x10
|
||||
1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 0x20
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, // 0x30
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // 0x50
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, // 0x70
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xe0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xf0
|
||||
};
|
90
net/http/khttptoken.S
Normal file
90
net/http/khttptoken.S
Normal file
|
@ -0,0 +1,90 @@
|
|||
#include "libc/macros.internal.h"
|
||||
|
||||
// generated by:
|
||||
// o//tool/build/xlat.com -TiC ' ()<>@,;:\"/[]?={}' -iskHttpToken
|
||||
//
|
||||
// present absent
|
||||
// ──────────────── ────────────────
|
||||
// ∅☺☻♥♦♣♠•◘○◙♂♀♪♫☼ 0x00
|
||||
// ►◄↕‼¶§▬↨↑↓→←∟↔▲▼ 0x10
|
||||
// ! #$%&‘ *+ -. ␠ “ () , / 0x20
|
||||
// 0123456789 :;<=>⁇ 0x30
|
||||
// ABCDEFGHIJKLMNO @ 0x40
|
||||
// PQRSTUVWXYZ ^_ [⭝] 0x50
|
||||
// `abcdefghijklmno 0x60
|
||||
// pqrstuvwxyz | ~ { } ⌂ 0x70
|
||||
// ÇüéâäàåçêëèïîìÄÅ 0x80
|
||||
// ÉæÆôöòûùÿÖÜ¢£¥€ƒ 0x90
|
||||
// áíóúñѪº¿⌐¬½¼¡«» 0xa0
|
||||
// ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐ 0xb0
|
||||
// └┴┬├─┼╞╟╚╔╩╦╠═╬╧ 0xc0
|
||||
// ╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ 0xd0
|
||||
// αßΓπΣσμτΦΘΩδ∞φε∩ 0xe0
|
||||
// ≡±≥≤⌠⌡÷≈°∙×√ⁿ²■λ 0xf0
|
||||
//
|
||||
// const char kHttpToken[256] = {
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10
|
||||
// 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 0x20
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 0x30
|
||||
// 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 0x50
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60
|
||||
// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, // 0x70
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x80
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x90
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xa0
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xb0
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xc0
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xd0
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xe0
|
||||
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xf0
|
||||
// };
|
||||
//
|
||||
// @see RFC2616
|
||||
// CHAR = <any US-ASCII character (octets 0 - 127)>
|
||||
// SP = <US-ASCII SP, space (32)>
|
||||
// HT = <US-ASCII HT, horizontal-tab (9)>
|
||||
// CTL = <any US-ASCII control character
|
||||
// (octets 0 - 31) and DEL (127)>
|
||||
// token = 1*<any CHAR except CTLs or separators>
|
||||
// separators = "(" | ")" | "<" | ">" | "@"
|
||||
// | "," | ";" | ":" | "\" | <">
|
||||
// | "/" | "[" | "]" | "?" | "="
|
||||
// | "{" | "}" | SP | HT
|
||||
|
||||
.initbss 300,_init_kHttpToken
|
||||
kHttpToken:
|
||||
.zero 256
|
||||
.endobj kHttpToken,globl
|
||||
.previous
|
||||
|
||||
.initro 300,_init_kHttpToken
|
||||
kHttpToken.rom:
|
||||
.byte 33,0 # 00-20 ∅-␠
|
||||
.byte 1,1 # 21-21 !-!
|
||||
.byte 1,0 # 22-22 “-“
|
||||
.byte 5,1 # 23-27 #-‘
|
||||
.byte 2,0 # 28-29 (-)
|
||||
.byte 2,1 # 2a-2b *-+
|
||||
.byte 1,0 # 2c-2c ,-,
|
||||
.byte 2,1 # 2d-2e --.
|
||||
.byte 1,0 # 2f-2f /-/
|
||||
.byte 10,1 # 30-39 0-9
|
||||
.byte 7,0 # 3a-40 :-@
|
||||
.byte 26,1 # 41-5a A-Z
|
||||
.byte 3,0 # 5b-5d [-]
|
||||
.byte 29,1 # 5e-7a ^-z
|
||||
.byte 1,0 # 7b-7b {-{
|
||||
.byte 1,1 # 7c-7c |-|
|
||||
.byte 1,0 # 7d-7d }-}
|
||||
.byte 1,1 # 7e-7e ~-~
|
||||
.byte 129,0 # 7f-ff ⌂-λ
|
||||
.byte 0,0 # terminator
|
||||
.endobj kHttpToken.rom,globl
|
||||
|
||||
.init.start 300,_init_kHttpToken
|
||||
call rldecode
|
||||
.init.end 300,_init_kHttpToken
|
||||
|
||||
// 45 bytes total (18% original size)
|
|
@ -1,42 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "net/http/http.h"
|
||||
|
||||
// http/1.1 token dispatch
|
||||
// 0 is CTLs, SP, ()<>@,;:\"/[]?={} which are illegal
|
||||
// 1 is everything else in ASCII which is legal
|
||||
// note that &" can break html
|
||||
const char kHttpToken[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10
|
||||
0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 0x20
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, // 0x30
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x40
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 0x50
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, // 0x70
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x80
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x90
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xa0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xb0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xc0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xd0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xe0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xf0
|
||||
};
|
|
@ -40,6 +40,7 @@
|
|||
#include "libc/x/x.h"
|
||||
#include "libc/zip.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
#include "third_party/zlib/puff.h"
|
||||
#include "third_party/zlib/zlib.h"
|
||||
|
||||
STATIC_YOINK("zip_uri_support");
|
||||
|
@ -133,7 +134,7 @@ void Inflate(void) {
|
|||
stream.avail_out = bufsize_;
|
||||
stream.total_out = bufsize_;
|
||||
CHECK_EQ(Z_OK, inflateInit2(&stream, -MAX_WBITS));
|
||||
CHECK_NE(Z_BUF_ERROR, inflate(&stream, Z_NO_FLUSH));
|
||||
CHECK_EQ(Z_STREAM_END, inflate(&stream, Z_FINISH));
|
||||
CHECK_EQ(Z_OK, inflateEnd(&stream));
|
||||
}
|
||||
|
||||
|
@ -141,6 +142,12 @@ void Undeflate(void) {
|
|||
undeflate(buf_, uncompressedsize_, data_, compressedsize_, &ds_);
|
||||
}
|
||||
|
||||
void Puff(void) {
|
||||
size_t insize = compressedsize_;
|
||||
size_t outsize = uncompressedsize_;
|
||||
CHECK_EQ(0, puff(buf_, &outsize, data_, &insize));
|
||||
}
|
||||
|
||||
BENCH(undeflate, bench) {
|
||||
size_t cf, lf;
|
||||
struct Zipos *zipos;
|
||||
|
@ -155,6 +162,7 @@ BENCH(undeflate, bench) {
|
|||
uncompressedsize_ = ZIP_LFILE_UNCOMPRESSEDSIZE(zipos->map + lf);
|
||||
bufsize_ = ROUNDUP(uncompressedsize_, FRAMESIZE / 2);
|
||||
buf_ = gc(malloc(bufsize_));
|
||||
EZBENCH(donothing, Puff());
|
||||
EZBENCH(donothing, Inflate());
|
||||
EZBENCH(donothing, Undeflate());
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ TEST(gcctls, size) {
|
|||
size = GetFileSize(GetProgramExecutableName());
|
||||
if (IsTiny()) {
|
||||
ASSERT_LT(size, 200 * 1024);
|
||||
} else if (IsModeDbg()) {
|
||||
} else if (IsModeDbg() || IsAsan()) {
|
||||
ASSERT_LT(size, 4 * 1024 * 1024);
|
||||
} else {
|
||||
ASSERT_LT(size, 500 * 1024);
|
||||
|
|
2
third_party/chibicc/chibicc.mk
vendored
2
third_party/chibicc/chibicc.mk
vendored
|
@ -116,7 +116,7 @@ o/$(MODE)/third_party/chibicc/chibicc.com: \
|
|||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/third_party/chibicc/.chibicc/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/third_party/chibicc/.chibicc/.symtab
|
||||
|
||||
o/$(MODE)/third_party/chibicc/as.com.dbg: \
|
||||
|
|
2
third_party/lua/lua.mk
vendored
2
third_party/lua/lua.mk
vendored
|
@ -78,7 +78,7 @@ o/$(MODE)/third_party/lua/lua.com: \
|
|||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/third_party/lua/.lua/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/third_party/lua/.lua/.symtab
|
||||
|
||||
o/$(MODE)/third_party/lua/lmathlib.o \
|
||||
|
|
2
third_party/make/make.mk
vendored
2
third_party/make/make.mk
vendored
|
@ -133,7 +133,7 @@ o/$(MODE)/third_party/make/make.com: \
|
|||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/third_party/make/.make/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/third_party/make/.make/.symtab
|
||||
|
||||
$(THIRD_PARTY_MAKE_OBJS): \
|
||||
|
|
6
third_party/mbedtls/ecp.c
vendored
6
third_party/mbedtls/ecp.c
vendored
|
@ -15,6 +15,7 @@
|
|||
│ See the License for the specific language governing permissions and │
|
||||
│ limitations under the License. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
@ -3340,11 +3341,14 @@ int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp,
|
|||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int rc;
|
||||
ECP_VALIDATE_RET( grp );
|
||||
ECP_VALIDATE_RET( d );
|
||||
ECP_VALIDATE_RET( Q );
|
||||
ECP_VALIDATE_RET( f_rng );
|
||||
return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) );
|
||||
rc = mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng );
|
||||
STRACE("%s() → %d", "mbedtls_ecp_gen_keypair", rc);
|
||||
return( rc );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
5
third_party/mbedtls/rsa.c
vendored
5
third_party/mbedtls/rsa.c
vendored
|
@ -15,6 +15,7 @@
|
|||
│ See the License for the specific language governing permissions and │
|
||||
│ limitations under the License. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
@ -570,9 +571,9 @@ cleanup:
|
|||
mbedtls_rsa_free( ctx );
|
||||
if( ( -ret & ~0x7f ) == 0 )
|
||||
ret = MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret;
|
||||
return( ret );
|
||||
}
|
||||
return( 0 );
|
||||
STRACE("%s() → %d", "mbedtls_rsa_gen_key", ret);
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#endif /* MBEDTLS_GENPRIME */
|
||||
|
|
3
third_party/mbedtls/zeroize.c
vendored
3
third_party/mbedtls/zeroize.c
vendored
|
@ -19,7 +19,8 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "third_party/mbedtls/platform.h"
|
||||
|
||||
void mbedtls_platform_zeroize(void *p, size_t n) {
|
||||
// disable ubsan because n=0 is defined behavior in cosmopolitan
|
||||
noubsan void mbedtls_platform_zeroize(void *p, size_t n) {
|
||||
MBEDTLS_INTERNAL_VALIDATE(!n || p);
|
||||
bzero(p, n);
|
||||
}
|
||||
|
|
2
third_party/python/python.mk
vendored
2
third_party/python/python.mk
vendored
|
@ -4280,7 +4280,7 @@ o/$(MODE)/third_party/python/python.com: \
|
|||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/third_party/python/.python/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/third_party/python/.python/.symtab
|
||||
|
||||
################################################################################
|
||||
|
|
2
third_party/quickjs/quickjs.mk
vendored
2
third_party/quickjs/quickjs.mk
vendored
|
@ -155,7 +155,7 @@ o/$(MODE)/third_party/quickjs/qjs.com: \
|
|||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/third_party/quickjs/.qjs/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/third_party/quickjs/.qjs/.symtab
|
||||
|
||||
o/$(MODE)/third_party/quickjs/qjsc.com.dbg: \
|
||||
|
|
2
third_party/sqlite3/sqlite3.mk
vendored
2
third_party/sqlite3/sqlite3.mk
vendored
|
@ -84,7 +84,7 @@ o/$(MODE)/third_party/sqlite3/sqlite3.com: \
|
|||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/third_party/sqlite3/.sqlite3/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/third_party/sqlite3/.sqlite3/.symtab
|
||||
|
||||
$(THIRD_PARTY_SQLITE3_A): \
|
||||
|
|
802
third_party/zlib/puff.c
vendored
Normal file
802
third_party/zlib/puff.c
vendored
Normal file
|
@ -0,0 +1,802 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "third_party/zlib/puff.h"
|
||||
// clang-format off
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
zlib (zlib License)\\n\
|
||||
Copyright 1995-2017 Jean-loup Gailly and Mark Adler\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
|
||||
/*
|
||||
* puff.c
|
||||
* Copyright (C) 2002-2013 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in puff.h
|
||||
* version 2.3, 21 Jan 2013
|
||||
*
|
||||
* puff.c is a simple inflate written to be an unambiguous way to specify the
|
||||
* deflate format. It is not written for speed but rather simplicity. As a
|
||||
* side benefit, this code might actually be useful when small code is more
|
||||
* important than speed, such as bootstrap applications. For typical deflate
|
||||
* data, zlib's inflate() is about four times as fast as puff(). zlib's
|
||||
* inflate compiles to around 20K on my machine, whereas puff.c compiles to
|
||||
* around 4K on my machine (a PowerPC using GNU cc). If the faster decode()
|
||||
* function here is used, then puff() is only twice as slow as zlib's
|
||||
* inflate().
|
||||
*
|
||||
* All dynamically allocated memory comes from the stack. The stack required
|
||||
* is less than 2K bytes. This code is compatible with 16-bit int's and
|
||||
* assumes that long's are at least 32 bits. puff.c uses the short data type,
|
||||
* assumed to be 16 bits, for arrays in order to conserve memory. The code
|
||||
* works whether integers are stored big endian or little endian.
|
||||
*
|
||||
* In the comments below are "Format notes" that describe the inflate process
|
||||
* and document some of the less obvious aspects of the format. This source
|
||||
* code is meant to supplement RFC 1951, which formally describes the deflate
|
||||
* format:
|
||||
*
|
||||
* http://www.zlib.org/rfc-deflate.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* Change history:
|
||||
*
|
||||
* 1.0 10 Feb 2002 - First version
|
||||
* 1.1 17 Feb 2002 - Clarifications of some comments and notes
|
||||
* - Update puff() dest and source pointers on negative
|
||||
* errors to facilitate debugging deflators
|
||||
* - Remove longest from struct huffman -- not needed
|
||||
* - Simplify offs[] index in construct()
|
||||
* - Add input size and checking, using longjmp() to
|
||||
* maintain easy readability
|
||||
* - Use short data type for large arrays
|
||||
* - Use pointers instead of long to specify source and
|
||||
* destination sizes to avoid arbitrary 4 GB limits
|
||||
* 1.2 17 Mar 2002 - Add faster version of decode(), doubles speed (!),
|
||||
* but leave simple version for readabilty
|
||||
* - Make sure invalid distances detected if pointers
|
||||
* are 16 bits
|
||||
* - Fix fixed codes table error
|
||||
* - Provide a scanning mode for determining size of
|
||||
* uncompressed data
|
||||
* 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Gailly]
|
||||
* - Add a puff.h file for the interface
|
||||
* - Add braces in puff() for else do [Gailly]
|
||||
* - Use indexes instead of pointers for readability
|
||||
* 1.4 31 Mar 2002 - Simplify construct() code set check
|
||||
* - Fix some comments
|
||||
* - Add FIXLCODES #define
|
||||
* 1.5 6 Apr 2002 - Minor comment fixes
|
||||
* 1.6 7 Aug 2002 - Minor format changes
|
||||
* 1.7 3 Mar 2003 - Added test code for distribution
|
||||
* - Added zlib-like license
|
||||
* 1.8 9 Jan 2004 - Added some comments on no distance codes case
|
||||
* 1.9 21 Feb 2008 - Fix bug on 16-bit integer architectures [Pohland]
|
||||
* - Catch missing end-of-block symbol error
|
||||
* 2.0 25 Jul 2008 - Add #define to permit distance too far back
|
||||
* - Add option in TEST code for puff to write the data
|
||||
* - Add option in TEST code to skip input bytes
|
||||
* - Allow TEST code to read from piped stdin
|
||||
* 2.1 4 Apr 2010 - Avoid variable initialization for happier compilers
|
||||
* - Avoid unsigned comparisons for even happier compilers
|
||||
* 2.2 25 Apr 2010 - Fix bug in variable initializations [Oberhumer]
|
||||
* - Add const where appropriate [Oberhumer]
|
||||
* - Split if's and ?'s for coverage testing
|
||||
* - Break out test code to separate file
|
||||
* - Move NIL to puff.h
|
||||
* - Allow incomplete code only if single code length is 1
|
||||
* - Add full code coverage test to Makefile
|
||||
* 2.3 21 Jan 2013 - Check for invalid code length codes in dynamic blocks
|
||||
*/
|
||||
|
||||
#ifndef NIL
|
||||
# define NIL ((unsigned char *)0) /* for no output option */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Maximums for allocations and loops. It is not useful to change these --
|
||||
* they are fixed by the deflate format.
|
||||
*/
|
||||
#define MAXBITS 15 /* maximum bits in a code */
|
||||
#define MAXLCODES 286 /* maximum number of literal/length codes */
|
||||
#define MAXDCODES 30 /* maximum number of distance codes */
|
||||
#define MAXCODES (MAXLCODES + MAXDCODES) /* maximum codes lengths to read */
|
||||
#define FIXLCODES 288 /* number of fixed literal/length codes */
|
||||
|
||||
/* input and output state */
|
||||
struct state {
|
||||
/* output state */
|
||||
unsigned char *out; /* output buffer */
|
||||
unsigned long outlen; /* available space at out */
|
||||
unsigned long outcnt; /* bytes written to out so far */
|
||||
|
||||
/* input state */
|
||||
const unsigned char *in; /* input buffer */
|
||||
unsigned long inlen; /* available input at in */
|
||||
unsigned long incnt; /* bytes read so far */
|
||||
int bitbuf; /* bit buffer */
|
||||
int bitcnt; /* number of bits in bit buffer */
|
||||
|
||||
/* input limit error return state for bits() and decode() */
|
||||
jmp_buf env;
|
||||
};
|
||||
|
||||
/*
|
||||
* Return need bits from the input stream. This always leaves less than
|
||||
* eight bits in the buffer. bits() works properly for need == 0.
|
||||
*
|
||||
* Format notes:
|
||||
*
|
||||
* - Bits are stored in bytes from the least significant bit to the most
|
||||
* significant bit. Therefore bits are dropped from the bottom of the bit
|
||||
* buffer, using shift right, and new bytes are appended to the top of the
|
||||
* bit buffer, using shift left.
|
||||
*/
|
||||
static int bits(struct state *s, int need) {
|
||||
long val; /* bit accumulator (can use up to 20 bits) */
|
||||
|
||||
/* load at least need bits into val */
|
||||
val = s->bitbuf;
|
||||
while (s->bitcnt < need) {
|
||||
if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
|
||||
val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
|
||||
s->bitcnt += 8;
|
||||
}
|
||||
|
||||
/* drop need bits and update buffer, always zero to seven bits left */
|
||||
s->bitbuf = (int)(val >> need);
|
||||
s->bitcnt -= need;
|
||||
|
||||
/* return need bits, zeroing the bits above that */
|
||||
return (int)(val & ((1L << need) - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a stored block.
|
||||
*
|
||||
* Format notes:
|
||||
*
|
||||
* - After the two-bit stored block type (00), the stored block length and
|
||||
* stored bytes are byte-aligned for fast copying. Therefore any leftover
|
||||
* bits in the byte that has the last bit of the type, as many as seven, are
|
||||
* discarded. The value of the discarded bits are not defined and should not
|
||||
* be checked against any expectation.
|
||||
*
|
||||
* - The second inverted copy of the stored block length does not have to be
|
||||
* checked, but it's probably a good idea to do so anyway.
|
||||
*
|
||||
* - A stored block can have zero length. This is sometimes used to byte-align
|
||||
* subsets of the compressed data for random access or partial recovery.
|
||||
*/
|
||||
static int stored(struct state *s) {
|
||||
unsigned len; /* length of stored block */
|
||||
|
||||
/* discard leftover bits from current byte (assumes s->bitcnt < 8) */
|
||||
s->bitbuf = 0;
|
||||
s->bitcnt = 0;
|
||||
|
||||
/* get length and check against its one's complement */
|
||||
if (s->incnt + 4 > s->inlen) return 2; /* not enough input */
|
||||
len = s->in[s->incnt++];
|
||||
len |= s->in[s->incnt++] << 8;
|
||||
if (s->in[s->incnt++] != (~len & 0xff) ||
|
||||
s->in[s->incnt++] != ((~len >> 8) & 0xff))
|
||||
return -2; /* didn't match complement! */
|
||||
|
||||
/* copy len bytes from in to out */
|
||||
if (s->incnt + len > s->inlen) return 2; /* not enough input */
|
||||
if (s->out != NIL) {
|
||||
if (s->outcnt + len > s->outlen) return 1; /* not enough output space */
|
||||
while (len--) s->out[s->outcnt++] = s->in[s->incnt++];
|
||||
} else { /* just scanning */
|
||||
s->outcnt += len;
|
||||
s->incnt += len;
|
||||
}
|
||||
|
||||
/* done with a valid stored block */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of
|
||||
* each length, which for a canonical code are stepped through in order.
|
||||
* symbol[] are the symbol values in canonical order, where the number of
|
||||
* entries is the sum of the counts in count[]. The decoding process can be
|
||||
* seen in the function decode() below.
|
||||
*/
|
||||
struct huffman {
|
||||
short *count; /* number of symbols of each length */
|
||||
short *symbol; /* canonically ordered symbols */
|
||||
};
|
||||
|
||||
/*
|
||||
* Decode a code from the stream s using huffman table h. Return the symbol or
|
||||
* a negative value if there is an error. If all of the lengths are zero, i.e.
|
||||
* an empty code, or if the code is incomplete and an invalid code is received,
|
||||
* then -10 is returned after reading MAXBITS bits.
|
||||
*
|
||||
* Format notes:
|
||||
*
|
||||
* - The codes as stored in the compressed data are bit-reversed relative to
|
||||
* a simple integer ordering of codes of the same lengths. Hence below the
|
||||
* bits are pulled from the compressed data one at a time and used to
|
||||
* build the code value reversed from what is in the stream in order to
|
||||
* permit simple integer comparisons for decoding. A table-based decoding
|
||||
* scheme (as used in zlib) does not need to do this reversal.
|
||||
*
|
||||
* - The first code for the shortest length is all zeros. Subsequent codes of
|
||||
* the same length are simply integer increments of the previous code. When
|
||||
* moving up a length, a zero bit is appended to the code. For a complete
|
||||
* code, the last code of the longest length will be all ones.
|
||||
*
|
||||
* - Incomplete codes are handled by this decoder, since they are permitted
|
||||
* in the deflate format. See the format notes for fixed() and dynamic().
|
||||
*/
|
||||
#ifdef SLOW
|
||||
static int decode(struct state *s, const struct huffman *h) {
|
||||
int len; /* current number of bits in code */
|
||||
int code; /* len bits being decoded */
|
||||
int first; /* first code of length len */
|
||||
int count; /* number of codes of length len */
|
||||
int index; /* index of first code of length len in symbol table */
|
||||
|
||||
code = first = index = 0;
|
||||
for (len = 1; len <= MAXBITS; len++) {
|
||||
code |= bits(s, 1); /* get next bit */
|
||||
count = h->count[len];
|
||||
if (code - count < first) /* if length len, return symbol */
|
||||
return h->symbol[index + (code - first)];
|
||||
index += count; /* else update for next length */
|
||||
first += count;
|
||||
first <<= 1;
|
||||
code <<= 1;
|
||||
}
|
||||
return -10; /* ran out of codes */
|
||||
}
|
||||
|
||||
/*
|
||||
* A faster version of decode() for real applications of this code. It's not
|
||||
* as readable, but it makes puff() twice as fast. And it only makes the code
|
||||
* a few percent larger.
|
||||
*/
|
||||
#else /* !SLOW */
|
||||
static int decode(struct state *s, const struct huffman *h) {
|
||||
int len; /* current number of bits in code */
|
||||
int code; /* len bits being decoded */
|
||||
int first; /* first code of length len */
|
||||
int count; /* number of codes of length len */
|
||||
int index; /* index of first code of length len in symbol table */
|
||||
int bitbuf; /* bits from stream */
|
||||
int left; /* bits left in next or left to process */
|
||||
short *next; /* next number of codes */
|
||||
|
||||
bitbuf = s->bitbuf;
|
||||
left = s->bitcnt;
|
||||
code = first = index = 0;
|
||||
len = 1;
|
||||
next = h->count + 1;
|
||||
while (1) {
|
||||
while (left--) {
|
||||
code |= bitbuf & 1;
|
||||
bitbuf >>= 1;
|
||||
count = *next++;
|
||||
if (code - count < first) { /* if length len, return symbol */
|
||||
s->bitbuf = bitbuf;
|
||||
s->bitcnt = (s->bitcnt - len) & 7;
|
||||
return h->symbol[index + (code - first)];
|
||||
}
|
||||
index += count; /* else update for next length */
|
||||
first += count;
|
||||
first <<= 1;
|
||||
code <<= 1;
|
||||
len++;
|
||||
}
|
||||
left = (MAXBITS + 1) - len;
|
||||
if (left == 0) break;
|
||||
if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
|
||||
bitbuf = s->in[s->incnt++];
|
||||
if (left > 8) left = 8;
|
||||
}
|
||||
return -10; /* ran out of codes */
|
||||
}
|
||||
#endif /* SLOW */
|
||||
|
||||
/*
|
||||
* Given the list of code lengths length[0..n-1] representing a canonical
|
||||
* Huffman code for n symbols, construct the tables required to decode those
|
||||
* codes. Those tables are the number of codes of each length, and the symbols
|
||||
* sorted by length, retaining their original order within each length. The
|
||||
* return value is zero for a complete code set, negative for an over-
|
||||
* subscribed code set, and positive for an incomplete code set. The tables
|
||||
* can be used if the return value is zero or positive, but they cannot be used
|
||||
* if the return value is negative. If the return value is zero, it is not
|
||||
* possible for decode() using that table to return an error--any stream of
|
||||
* enough bits will resolve to a symbol. If the return value is positive, then
|
||||
* it is possible for decode() using that table to return an error for received
|
||||
* codes past the end of the incomplete lengths.
|
||||
*
|
||||
* Not used by decode(), but used for error checking, h->count[0] is the number
|
||||
* of the n symbols not in the code. So n - h->count[0] is the number of
|
||||
* codes. This is useful for checking for incomplete codes that have more than
|
||||
* one symbol, which is an error in a dynamic block.
|
||||
*
|
||||
* Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS
|
||||
* This is assured by the construction of the length arrays in dynamic() and
|
||||
* fixed() and is not verified by construct().
|
||||
*
|
||||
* Format notes:
|
||||
*
|
||||
* - Permitted and expected examples of incomplete codes are one of the fixed
|
||||
* codes and any code with a single symbol which in deflate is coded as one
|
||||
* bit instead of zero bits. See the format notes for fixed() and dynamic().
|
||||
*
|
||||
* - Within a given code length, the symbols are kept in ascending order for
|
||||
* the code bits definition.
|
||||
*/
|
||||
static int construct(struct huffman *h, const short *length, int n) {
|
||||
int symbol; /* current symbol when stepping through length[] */
|
||||
int len; /* current length when stepping through h->count[] */
|
||||
int left; /* number of possible codes left of current length */
|
||||
short offs[MAXBITS + 1]; /* offsets in symbol table for each length */
|
||||
|
||||
/* count number of codes of each length */
|
||||
for (len = 0; len <= MAXBITS; len++) h->count[len] = 0;
|
||||
for (symbol = 0; symbol < n; symbol++)
|
||||
(h->count[length[symbol]])++; /* assumes lengths are within bounds */
|
||||
if (h->count[0] == n) /* no codes! */
|
||||
return 0; /* complete, but decode() will fail */
|
||||
|
||||
/* check for an over-subscribed or incomplete set of lengths */
|
||||
left = 1; /* one possible code of zero length */
|
||||
for (len = 1; len <= MAXBITS; len++) {
|
||||
left <<= 1; /* one more bit, double codes left */
|
||||
left -= h->count[len]; /* deduct count from possible codes */
|
||||
if (left < 0) return left; /* over-subscribed--return negative */
|
||||
} /* left > 0 means incomplete */
|
||||
|
||||
/* generate offsets into symbol table for each length for sorting */
|
||||
offs[1] = 0;
|
||||
for (len = 1; len < MAXBITS; len++) offs[len + 1] = offs[len] + h->count[len];
|
||||
|
||||
/*
|
||||
* put symbols in table sorted by length, by symbol order within each
|
||||
* length
|
||||
*/
|
||||
for (symbol = 0; symbol < n; symbol++)
|
||||
if (length[symbol] != 0) h->symbol[offs[length[symbol]]++] = symbol;
|
||||
|
||||
/* return zero for complete set, positive for incomplete set */
|
||||
return left;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode literal/length and distance codes until an end-of-block code.
|
||||
*
|
||||
* Format notes:
|
||||
*
|
||||
* - Compressed data that is after the block type if fixed or after the code
|
||||
* description if dynamic is a combination of literals and length/distance
|
||||
* pairs terminated by and end-of-block code. Literals are simply Huffman
|
||||
* coded bytes. A length/distance pair is a coded length followed by a
|
||||
* coded distance to represent a string that occurs earlier in the
|
||||
* uncompressed data that occurs again at the current location.
|
||||
*
|
||||
* - Literals, lengths, and the end-of-block code are combined into a single
|
||||
* code of up to 286 symbols. They are 256 literals (0..255), 29 length
|
||||
* symbols (257..285), and the end-of-block symbol (256).
|
||||
*
|
||||
* - There are 256 possible lengths (3..258), and so 29 symbols are not enough
|
||||
* to represent all of those. Lengths 3..10 and 258 are in fact represented
|
||||
* by just a length symbol. Lengths 11..257 are represented as a symbol and
|
||||
* some number of extra bits that are added as an integer to the base length
|
||||
* of the length symbol. The number of extra bits is determined by the base
|
||||
* length symbol. These are in the static arrays below, lens[] for the base
|
||||
* lengths and lext[] for the corresponding number of extra bits.
|
||||
*
|
||||
* - The reason that 258 gets its own symbol is that the longest length is used
|
||||
* often in highly redundant files. Note that 258 can also be coded as the
|
||||
* base value 227 plus the maximum extra value of 31. While a good deflate
|
||||
* should never do this, it is not an error, and should be decoded properly.
|
||||
*
|
||||
* - If a length is decoded, including its extra bits if any, then it is
|
||||
* followed a distance code. There are up to 30 distance symbols. Again
|
||||
* there are many more possible distances (1..32768), so extra bits are added
|
||||
* to a base value represented by the symbol. The distances 1..4 get their
|
||||
* own symbol, but the rest require extra bits. The base distances and
|
||||
* corresponding number of extra bits are below in the static arrays dist[]
|
||||
* and dext[].
|
||||
*
|
||||
* - Literal bytes are simply written to the output. A length/distance pair is
|
||||
* an instruction to copy previously uncompressed bytes to the output. The
|
||||
* copy is from distance bytes back in the output stream, copying for length
|
||||
* bytes.
|
||||
*
|
||||
* - Distances pointing before the beginning of the output data are not
|
||||
* permitted.
|
||||
*
|
||||
* - Overlapped copies, where the length is greater than the distance, are
|
||||
* allowed and common. For example, a distance of one and a length of 258
|
||||
* simply copies the last byte 258 times. A distance of four and a length of
|
||||
* twelve copies the last four bytes three times. A simple forward copy
|
||||
* ignoring whether the length is greater than the distance or not implements
|
||||
* this correctly. You should not use memcpy() since its behavior is not
|
||||
* defined for overlapped arrays. You should not use memmove() or bcopy()
|
||||
* since though their behavior -is- defined for overlapping arrays, it is
|
||||
* defined to do the wrong thing in this case.
|
||||
*/
|
||||
static int codes(struct state *s, const struct huffman *lencode,
|
||||
const struct huffman *distcode) {
|
||||
int symbol; /* decoded symbol */
|
||||
int len; /* length for copy */
|
||||
unsigned dist; /* distance for copy */
|
||||
static const short lens[29] = {/* Size base for length codes 257..285 */
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
|
||||
15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
|
||||
67, 83, 99, 115, 131, 163, 195, 227, 258};
|
||||
static const short lext[29] = {/* Extra bits for length codes 257..285 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2,
|
||||
2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
|
||||
static const short dists[30] = {
|
||||
/* Offset base for distance codes 0..29 */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25,
|
||||
33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
|
||||
1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
|
||||
static const short dext[30] = {/* Extra bits for distance codes 0..29 */
|
||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
|
||||
4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
|
||||
9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
|
||||
|
||||
/* decode literals and length/distance pairs */
|
||||
do {
|
||||
symbol = decode(s, lencode);
|
||||
if (symbol < 0) return symbol; /* invalid symbol */
|
||||
if (symbol < 256) { /* literal: symbol is the byte */
|
||||
/* write out the literal */
|
||||
if (s->out != NIL) {
|
||||
if (s->outcnt == s->outlen) return 1;
|
||||
s->out[s->outcnt] = symbol;
|
||||
}
|
||||
s->outcnt++;
|
||||
} else if (symbol > 256) { /* length */
|
||||
/* get and compute length */
|
||||
symbol -= 257;
|
||||
if (symbol >= 29) return -10; /* invalid fixed code */
|
||||
len = lens[symbol] + bits(s, lext[symbol]);
|
||||
|
||||
/* get and check distance */
|
||||
symbol = decode(s, distcode);
|
||||
if (symbol < 0) return symbol; /* invalid symbol */
|
||||
dist = dists[symbol] + bits(s, dext[symbol]);
|
||||
#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||||
if (dist > s->outcnt) return -11; /* distance too far back */
|
||||
#endif
|
||||
|
||||
/* copy length bytes from distance bytes back */
|
||||
if (s->out != NIL) {
|
||||
if (s->outcnt + len > s->outlen) return 1;
|
||||
while (len--) {
|
||||
s->out[s->outcnt] =
|
||||
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||||
dist > s->outcnt ? 0 :
|
||||
#endif
|
||||
s->out[s->outcnt - dist];
|
||||
s->outcnt++;
|
||||
}
|
||||
} else
|
||||
s->outcnt += len;
|
||||
}
|
||||
} while (symbol != 256); /* end of block symbol */
|
||||
|
||||
/* done with a valid fixed or dynamic block */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a fixed codes block.
|
||||
*
|
||||
* Format notes:
|
||||
*
|
||||
* - This block type can be useful for compressing small amounts of data for
|
||||
* which the size of the code descriptions in a dynamic block exceeds the
|
||||
* benefit of custom codes for that block. For fixed codes, no bits are
|
||||
* spent on code descriptions. Instead the code lengths for literal/length
|
||||
* codes and distance codes are fixed. The specific lengths for each symbol
|
||||
* can be seen in the "for" loops below.
|
||||
*
|
||||
* - The literal/length code is complete, but has two symbols that are invalid
|
||||
* and should result in an error if received. This cannot be implemented
|
||||
* simply as an incomplete code since those two symbols are in the "middle"
|
||||
* of the code. They are eight bits long and the longest literal/length\
|
||||
* code is nine bits. Therefore the code must be constructed with those
|
||||
* symbols, and the invalid symbols must be detected after decoding.
|
||||
*
|
||||
* - The fixed distance codes also have two invalid symbols that should result
|
||||
* in an error if received. Since all of the distance codes are the same
|
||||
* length, this can be implemented as an incomplete code. Then the invalid
|
||||
* codes are detected while decoding.
|
||||
*/
|
||||
static int fixed(struct state *s) {
|
||||
static int virgin = 1;
|
||||
static short lencnt[MAXBITS + 1], lensym[FIXLCODES];
|
||||
static short distcnt[MAXBITS + 1], distsym[MAXDCODES];
|
||||
static struct huffman lencode, distcode;
|
||||
|
||||
/* build fixed huffman tables if first call (may not be thread safe) */
|
||||
if (virgin) {
|
||||
int symbol;
|
||||
short lengths[FIXLCODES];
|
||||
|
||||
/* construct lencode and distcode */
|
||||
lencode.count = lencnt;
|
||||
lencode.symbol = lensym;
|
||||
distcode.count = distcnt;
|
||||
distcode.symbol = distsym;
|
||||
|
||||
/* literal/length table */
|
||||
for (symbol = 0; symbol < 144; symbol++) lengths[symbol] = 8;
|
||||
for (; symbol < 256; symbol++) lengths[symbol] = 9;
|
||||
for (; symbol < 280; symbol++) lengths[symbol] = 7;
|
||||
for (; symbol < FIXLCODES; symbol++) lengths[symbol] = 8;
|
||||
construct(&lencode, lengths, FIXLCODES);
|
||||
|
||||
/* distance table */
|
||||
for (symbol = 0; symbol < MAXDCODES; symbol++) lengths[symbol] = 5;
|
||||
construct(&distcode, lengths, MAXDCODES);
|
||||
|
||||
/* do this just once */
|
||||
virgin = 0;
|
||||
}
|
||||
|
||||
/* decode data until end-of-block code */
|
||||
return codes(s, &lencode, &distcode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a dynamic codes block.
|
||||
*
|
||||
* Format notes:
|
||||
*
|
||||
* - A dynamic block starts with a description of the literal/length and
|
||||
* distance codes for that block. New dynamic blocks allow the compressor to
|
||||
* rapidly adapt to changing data with new codes optimized for that data.
|
||||
*
|
||||
* - The codes used by the deflate format are "canonical", which means that
|
||||
* the actual bits of the codes are generated in an unambiguous way simply
|
||||
* from the number of bits in each code. Therefore the code descriptions
|
||||
* are simply a list of code lengths for each symbol.
|
||||
*
|
||||
* - The code lengths are stored in order for the symbols, so lengths are
|
||||
* provided for each of the literal/length symbols, and for each of the
|
||||
* distance symbols.
|
||||
*
|
||||
* - If a symbol is not used in the block, this is represented by a zero as
|
||||
* as the code length. This does not mean a zero-length code, but rather
|
||||
* that no code should be created for this symbol. There is no way in the
|
||||
* deflate format to represent a zero-length code.
|
||||
*
|
||||
* - The maximum number of bits in a code is 15, so the possible lengths for
|
||||
* any code are 1..15.
|
||||
*
|
||||
* - The fact that a length of zero is not permitted for a code has an
|
||||
* interesting consequence. Normally if only one symbol is used for a given
|
||||
* code, then in fact that code could be represented with zero bits. However
|
||||
* in deflate, that code has to be at least one bit. So for example, if
|
||||
* only a single distance base symbol appears in a block, then it will be
|
||||
* represented by a single code of length one, in particular one 0 bit. This
|
||||
* is an incomplete code, since if a 1 bit is received, it has no meaning,
|
||||
* and should result in an error. So incomplete distance codes of one symbol
|
||||
* should be permitted, and the receipt of invalid codes should be handled.
|
||||
*
|
||||
* - It is also possible to have a single literal/length code, but that code
|
||||
* must be the end-of-block code, since every dynamic block has one. This
|
||||
* is not the most efficient way to create an empty block (an empty fixed
|
||||
* block is fewer bits), but it is allowed by the format. So incomplete
|
||||
* literal/length codes of one symbol should also be permitted.
|
||||
*
|
||||
* - If there are only literal codes and no lengths, then there are no distance
|
||||
* codes. This is represented by one distance code with zero bits.
|
||||
*
|
||||
* - The list of up to 286 length/literal lengths and up to 30 distance lengths
|
||||
* are themselves compressed using Huffman codes and run-length encoding. In
|
||||
* the list of code lengths, a 0 symbol means no code, a 1..15 symbol means
|
||||
* that length, and the symbols 16, 17, and 18 are run-length instructions.
|
||||
* Each of 16, 17, and 18 are follwed by extra bits to define the length of
|
||||
* the run. 16 copies the last length 3 to 6 times. 17 represents 3 to 10
|
||||
* zero lengths, and 18 represents 11 to 138 zero lengths. Unused symbols
|
||||
* are common, hence the special coding for zero lengths.
|
||||
*
|
||||
* - The symbols for 0..18 are Huffman coded, and so that code must be
|
||||
* described first. This is simply a sequence of up to 19 three-bit values
|
||||
* representing no code (0) or the code length for that symbol (1..7).
|
||||
*
|
||||
* - A dynamic block starts with three fixed-size counts from which is computed
|
||||
* the number of literal/length code lengths, the number of distance code
|
||||
* lengths, and the number of code length code lengths (ok, you come up with
|
||||
* a better name!) in the code descriptions. For the literal/length and
|
||||
* distance codes, lengths after those provided are considered zero, i.e. no
|
||||
* code. The code length code lengths are received in a permuted order (see
|
||||
* the order[] array below) to make a short code length code length list more
|
||||
* likely. As it turns out, very short and very long codes are less likely
|
||||
* to be seen in a dynamic code description, hence what may appear initially
|
||||
* to be a peculiar ordering.
|
||||
*
|
||||
* - Given the number of literal/length code lengths (nlen) and distance code
|
||||
* lengths (ndist), then they are treated as one long list of nlen + ndist
|
||||
* code lengths. Therefore run-length coding can and often does cross the
|
||||
* boundary between the two sets of lengths.
|
||||
*
|
||||
* - So to summarize, the code description at the start of a dynamic block is
|
||||
* three counts for the number of code lengths for the literal/length codes,
|
||||
* the distance codes, and the code length codes. This is followed by the
|
||||
* code length code lengths, three bits each. This is used to construct the
|
||||
* code length code which is used to read the remainder of the lengths. Then
|
||||
* the literal/length code lengths and distance lengths are read as a single
|
||||
* set of lengths using the code length codes. Codes are constructed from
|
||||
* the resulting two sets of lengths, and then finally you can start
|
||||
* decoding actual compressed data in the block.
|
||||
*
|
||||
* - For reference, a "typical" size for the code description in a dynamic
|
||||
* block is around 80 bytes.
|
||||
*/
|
||||
static int dynamic(struct state *s) {
|
||||
int nlen, ndist, ncode; /* number of lengths in descriptor */
|
||||
int index; /* index of lengths[] */
|
||||
int err; /* construct() return value */
|
||||
short lengths[MAXCODES]; /* descriptor code lengths */
|
||||
short lencnt[MAXBITS + 1], lensym[MAXLCODES]; /* lencode memory */
|
||||
short distcnt[MAXBITS + 1], distsym[MAXDCODES]; /* distcode memory */
|
||||
struct huffman lencode, distcode; /* length and distance codes */
|
||||
static const short order[19] = /* permutation of code length codes */
|
||||
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
|
||||
/* construct lencode and distcode */
|
||||
lencode.count = lencnt;
|
||||
lencode.symbol = lensym;
|
||||
distcode.count = distcnt;
|
||||
distcode.symbol = distsym;
|
||||
|
||||
/* get number of lengths in each table, check lengths */
|
||||
nlen = bits(s, 5) + 257;
|
||||
ndist = bits(s, 5) + 1;
|
||||
ncode = bits(s, 4) + 4;
|
||||
if (nlen > MAXLCODES || ndist > MAXDCODES) return -3; /* bad counts */
|
||||
|
||||
/* read code length code lengths (really), missing lengths are zero */
|
||||
for (index = 0; index < ncode; index++) lengths[order[index]] = bits(s, 3);
|
||||
for (; index < 19; index++) lengths[order[index]] = 0;
|
||||
|
||||
/* build huffman table for code lengths codes (use lencode temporarily) */
|
||||
err = construct(&lencode, lengths, 19);
|
||||
if (err != 0) /* require complete code set here */
|
||||
return -4;
|
||||
|
||||
/* read length/literal and distance code length tables */
|
||||
index = 0;
|
||||
while (index < nlen + ndist) {
|
||||
int symbol; /* decoded value */
|
||||
int len; /* last length to repeat */
|
||||
|
||||
symbol = decode(s, &lencode);
|
||||
if (symbol < 0) return symbol; /* invalid symbol */
|
||||
if (symbol < 16) /* length in 0..15 */
|
||||
lengths[index++] = symbol;
|
||||
else { /* repeat instruction */
|
||||
len = 0; /* assume repeating zeros */
|
||||
if (symbol == 16) { /* repeat last length 3..6 times */
|
||||
if (index == 0) return -5; /* no last length! */
|
||||
len = lengths[index - 1]; /* last length */
|
||||
symbol = 3 + bits(s, 2);
|
||||
} else if (symbol == 17) /* repeat zero 3..10 times */
|
||||
symbol = 3 + bits(s, 3);
|
||||
else /* == 18, repeat zero 11..138 times */
|
||||
symbol = 11 + bits(s, 7);
|
||||
if (index + symbol > nlen + ndist) return -6; /* too many lengths! */
|
||||
while (symbol--) /* repeat last or zero symbol times */
|
||||
lengths[index++] = len;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for end-of-block code -- there better be one! */
|
||||
if (lengths[256] == 0) return -9;
|
||||
|
||||
/* build huffman table for literal/length codes */
|
||||
err = construct(&lencode, lengths, nlen);
|
||||
if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
|
||||
return -7; /* incomplete code ok only for single length 1 code */
|
||||
|
||||
/* build huffman table for distance codes */
|
||||
err = construct(&distcode, lengths + nlen, ndist);
|
||||
if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
|
||||
return -8; /* incomplete code ok only for single length 1 code */
|
||||
|
||||
/* decode data until end-of-block code */
|
||||
return codes(s, &lencode, &distcode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Inflate source to dest. On return, destlen and sourcelen are updated to the
|
||||
* size of the uncompressed data and the size of the deflate data respectively.
|
||||
* On success, the return value of puff() is zero. If there is an error in the
|
||||
* source data, i.e. it is not in the deflate format, then a negative value is
|
||||
* returned. If there is not enough input available or there is not enough
|
||||
* output space, then a positive error is returned. In that case, destlen and
|
||||
* sourcelen are not updated to facilitate retrying from the beginning with the
|
||||
* provision of more input data or more output space. In the case of invalid
|
||||
* inflate data (a negative error), the dest and source pointers are updated to
|
||||
* facilitate the debugging of deflators.
|
||||
*
|
||||
* puff() also has a mode to determine the size of the uncompressed output with
|
||||
* no output written. For this dest must be (unsigned char *)0. In this case,
|
||||
* the input value of *destlen is ignored, and on return *destlen is set to the
|
||||
* size of the uncompressed output.
|
||||
*
|
||||
* The return codes are:
|
||||
*
|
||||
* 2: available inflate data did not terminate
|
||||
* 1: output space exhausted before completing inflate
|
||||
* 0: successful inflate
|
||||
* -1: invalid block type (type == 3)
|
||||
* -2: stored block length did not match one's complement
|
||||
* -3: dynamic block code description: too many length or distance codes
|
||||
* -4: dynamic block code description: code lengths codes incomplete
|
||||
* -5: dynamic block code description: repeat lengths with no first length
|
||||
* -6: dynamic block code description: repeat more than specified lengths
|
||||
* -7: dynamic block code description: invalid literal/length code lengths
|
||||
* -8: dynamic block code description: invalid distance code lengths
|
||||
* -9: dynamic block code description: missing end-of-block code
|
||||
* -10: invalid literal/length or distance code in fixed or dynamic block
|
||||
* -11: distance is too far back in fixed or dynamic block
|
||||
*
|
||||
* Format notes:
|
||||
*
|
||||
* - Three bits are read for each block to determine the kind of block and
|
||||
* whether or not it is the last block. Then the block is decoded and the
|
||||
* process repeated if it was not the last block.
|
||||
*
|
||||
* - The leftover bits in the last byte of the deflate data after the last
|
||||
* block (if it was a fixed or dynamic block) are undefined and have no
|
||||
* expected values to check.
|
||||
*/
|
||||
int puff(unsigned char *dest, /* pointer to destination pointer */
|
||||
unsigned long *destlen, /* amount of output space */
|
||||
const unsigned char *source, /* pointer to source data pointer */
|
||||
unsigned long *sourcelen) /* amount of input available */
|
||||
{
|
||||
struct state s; /* input/output state */
|
||||
int last, type; /* block information */
|
||||
int err; /* return value */
|
||||
|
||||
/* initialize output state */
|
||||
s.out = dest;
|
||||
s.outlen = *destlen; /* ignored if dest is NIL */
|
||||
s.outcnt = 0;
|
||||
|
||||
/* initialize input state */
|
||||
s.in = source;
|
||||
s.inlen = *sourcelen;
|
||||
s.incnt = 0;
|
||||
s.bitbuf = 0;
|
||||
s.bitcnt = 0;
|
||||
|
||||
/* return if bits() or decode() tries to read past available input */
|
||||
if (setjmp(s.env) != 0) /* if came back here via longjmp() */
|
||||
err = 2; /* then skip do-loop, return error */
|
||||
else {
|
||||
/* process blocks until last block or error */
|
||||
do {
|
||||
last = bits(&s, 1); /* one if last block */
|
||||
type = bits(&s, 2); /* block type 0..3 */
|
||||
err = type == 0 ? stored(&s)
|
||||
: (type == 1 ? fixed(&s)
|
||||
: (type == 2 ? dynamic(&s)
|
||||
: -1)); /* type == 3, invalid */
|
||||
if (err != 0) break; /* return with error */
|
||||
} while (!last);
|
||||
}
|
||||
|
||||
/* update the lengths and return */
|
||||
if (err <= 0) {
|
||||
*destlen = s.outcnt;
|
||||
*sourcelen = s.incnt;
|
||||
}
|
||||
return err;
|
||||
}
|
11
third_party/zlib/puff.h
vendored
Normal file
11
third_party/zlib/puff.h
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef COSMOPOLITAN_THIRD_PARTY_ZLIB_PUFF_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_ZLIB_PUFF_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int puff(unsigned char *dest, unsigned long *destlen,
|
||||
const unsigned char *source, unsigned long *sourcelen);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_ZLIB_PUFF_H_ */
|
2
third_party/zlib/zlib.mk
vendored
2
third_party/zlib/zlib.mk
vendored
|
@ -7,7 +7,7 @@ THIRD_PARTY_ZLIB_ARTIFACTS += THIRD_PARTY_ZLIB_A
|
|||
THIRD_PARTY_ZLIB = $(THIRD_PARTY_ZLIB_A_DEPS) $(THIRD_PARTY_ZLIB_A)
|
||||
THIRD_PARTY_ZLIB_A = o/$(MODE)/third_party/zlib/zlib.a
|
||||
THIRD_PARTY_ZLIB_A_FILES := $(wildcard third_party/zlib/*)
|
||||
THIRD_PARTY_ZLIB_A_HDRS = third_party/zlib/zlib.h
|
||||
THIRD_PARTY_ZLIB_A_HDRS = third_party/zlib/zlib.h third_party/zlib/puff.h
|
||||
THIRD_PARTY_ZLIB_A_HDRS_ALL = $(filter %.h,$(THIRD_PARTY_ZLIB_A_FILES))
|
||||
THIRD_PARTY_ZLIB_A_SRCS_S = $(filter %.S,$(THIRD_PARTY_ZLIB_A_FILES))
|
||||
THIRD_PARTY_ZLIB_A_SRCS_C = $(filter %.c,$(THIRD_PARTY_ZLIB_A_FILES))
|
||||
|
|
|
@ -99,7 +99,7 @@ o/$(MODE)/tool/build/blinkenlights.com: \
|
|||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/build/.blinkenlights/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/build/.blinkenlights/.symtab
|
||||
|
||||
o/$(MODE)/tool/build/ar.com.dbg: \
|
||||
|
|
323
tool/build/xlat.c
Normal file
323
tool/build/xlat.c
Normal file
|
@ -0,0 +1,323 @@
|
|||
/*-*- 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 2022 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 │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Tool for generating rldecode'd character sets, e.g.
|
||||
*
|
||||
* # generate http token table
|
||||
* o//tool/build/xlat.com -TiC ' ()<>@,;:\"/[]?={}' -i
|
||||
*/
|
||||
|
||||
int dig;
|
||||
int xlat[256];
|
||||
const char *symbol;
|
||||
|
||||
static int Bing(int c) {
|
||||
if (!c) return L'∅';
|
||||
if (c == ' ') return L'␠';
|
||||
if (c == '$') return L'§';
|
||||
if (c == '\\') return L'⭝';
|
||||
return kCp437[c & 255];
|
||||
}
|
||||
|
||||
static void Fill(int f(int)) {
|
||||
int i;
|
||||
for (i = 0; i < 256; ++i) {
|
||||
if (f(i)) {
|
||||
xlat[i] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Invert(void) {
|
||||
int i;
|
||||
for (i = 0; i < 256; ++i) {
|
||||
xlat[i] = !xlat[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void Negate(void) {
|
||||
int i;
|
||||
for (i = 0; i < 256; ++i) {
|
||||
xlat[i] = ~xlat[i] & 255;
|
||||
}
|
||||
}
|
||||
|
||||
static void Negative(void) {
|
||||
int i;
|
||||
for (i = 0; i < 256; ++i) {
|
||||
xlat[i] = -xlat[i] & 255;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ArgNeedsShellQuotes(const char *s) {
|
||||
if (*s) {
|
||||
for (;;) {
|
||||
switch (*s++ & 255) {
|
||||
case 0:
|
||||
return false;
|
||||
case '-':
|
||||
case '.':
|
||||
case '/':
|
||||
case '_':
|
||||
case '=':
|
||||
case ':':
|
||||
case '0' ... '9':
|
||||
case 'A' ... 'Z':
|
||||
case 'a' ... 'z':
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static char *AddShellQuotes(const char *s) {
|
||||
char *p, *q;
|
||||
size_t i, j, n;
|
||||
n = strlen(s);
|
||||
p = malloc(1 + n * 5 + 1 + 1);
|
||||
j = 0;
|
||||
p[j++] = '\'';
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (s[i] != '\'') {
|
||||
p[j++] = s[i];
|
||||
} else {
|
||||
p[j + 0] = '\'';
|
||||
p[j + 1] = '"';
|
||||
p[j + 2] = '\'';
|
||||
p[j + 3] = '"';
|
||||
p[j + 4] = '\'';
|
||||
j += 5;
|
||||
}
|
||||
}
|
||||
p[j++] = '\'';
|
||||
p[j] = 0;
|
||||
if ((q = realloc(p, j + 1))) p = q;
|
||||
return p;
|
||||
}
|
||||
|
||||
static const char *GetArg(char *argv[], int i, int *k) {
|
||||
if (argv[*k][i + 1]) {
|
||||
return argv[*k] + i + 1;
|
||||
} else {
|
||||
return argv[++*k];
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const char *arg;
|
||||
int i, j, k, opt;
|
||||
dig = 1;
|
||||
symbol = "kXlatTab";
|
||||
|
||||
for (k = 1; k < argc; ++k) {
|
||||
if (argv[k][0] != '-') {
|
||||
for (i = 0; argv[k][i]; ++i) {
|
||||
xlat[argv[k][i] & 255] = dig;
|
||||
}
|
||||
} else {
|
||||
i = 0;
|
||||
moar:
|
||||
++i;
|
||||
if ((opt = argv[k][i])) {
|
||||
switch (opt) {
|
||||
case 's':
|
||||
symbol = GetArg(argv, i, &k);
|
||||
break;
|
||||
case 'x':
|
||||
dig = atoi(GetArg(argv, i, &k)) & 255;
|
||||
break;
|
||||
case 'i':
|
||||
Invert();
|
||||
goto moar;
|
||||
case 'n':
|
||||
Negative();
|
||||
goto moar;
|
||||
case 'N':
|
||||
Negate();
|
||||
goto moar;
|
||||
case 'T':
|
||||
Fill(isascii);
|
||||
goto moar;
|
||||
case 'C':
|
||||
Fill(iscntrl);
|
||||
goto moar;
|
||||
case 'A':
|
||||
Fill(isalpha);
|
||||
goto moar;
|
||||
case 'B':
|
||||
Fill(isblank);
|
||||
goto moar;
|
||||
case 'G':
|
||||
Fill(isgraph);
|
||||
goto moar;
|
||||
case 'P':
|
||||
Fill(ispunct);
|
||||
goto moar;
|
||||
case 'D':
|
||||
Fill(isdigit);
|
||||
goto moar;
|
||||
case 'U':
|
||||
Fill(isupper);
|
||||
goto moar;
|
||||
case 'L':
|
||||
Fill(islower);
|
||||
goto moar;
|
||||
default:
|
||||
fprintf(stderr, "error: unrecognized option: %c\n", opt);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
printf("#include \"libc/macros.internal.h\"\n");
|
||||
printf("\n");
|
||||
|
||||
printf("//\tgenerated by:\n");
|
||||
printf("//\t");
|
||||
for (i = 0; i < argc; ++i) {
|
||||
if (i) printf(" ");
|
||||
printf("%s", !ArgNeedsShellQuotes(argv[i]) ? argv[i]
|
||||
: gc(AddShellQuotes(argv[i])));
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
printf("//\n");
|
||||
printf("//\t present absent\n");
|
||||
printf("//\t ──────────────── ────────────────\n");
|
||||
for (i = 0; i < 16; ++i) {
|
||||
char16_t absent[16];
|
||||
char16_t present[16];
|
||||
for (j = 0; j < 16; ++j) {
|
||||
if (xlat[i * 16 + j]) {
|
||||
absent[j] = L' ';
|
||||
present[j] = Bing(i * 16 + j);
|
||||
} else {
|
||||
absent[j] = Bing(i * 16 + j);
|
||||
present[j] = L' ';
|
||||
}
|
||||
}
|
||||
printf("//\t %.16hs %.16hs 0x%02x\n", present, absent, i * 16);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
printf("//\n");
|
||||
printf("//\tconst char %s[256] = {\n//\t", symbol);
|
||||
for (i = 0; i < 16; ++i) {
|
||||
printf(" ");
|
||||
for (j = 0; j < 16; ++j) {
|
||||
printf("%2d,", xlat[i * 16 + j]);
|
||||
}
|
||||
printf(" // 0x%02x\n//\t", i * 16);
|
||||
}
|
||||
printf("};\n");
|
||||
printf("\n");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
printf("\t.initbss 300,_init_%s\n", symbol);
|
||||
printf("%s:\n", symbol);
|
||||
printf("\t.zero\t256\n");
|
||||
printf("\t.endobj\t%s,globl\n", symbol);
|
||||
printf("\t.previous\n");
|
||||
printf("\n");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
printf("\t.initro 300,_init_%s\n", symbol);
|
||||
printf("%s.rom:\n", symbol);
|
||||
|
||||
int thebloat = 0;
|
||||
int thetally = 0;
|
||||
int thecount = 0;
|
||||
int runstart = 0;
|
||||
int runchar = -1;
|
||||
int runcount = 0;
|
||||
for (i = 0;; ++i) {
|
||||
if (i < 256 && xlat[i] == runchar) {
|
||||
++runcount;
|
||||
} else {
|
||||
if (runcount) {
|
||||
printf("\t.byte\t%-24s# %02x-%02x %hc-%hc\n",
|
||||
gc(xasprintf("%3d,%d", runcount, runchar)), runstart,
|
||||
runstart + runcount - 1, Bing(runstart),
|
||||
Bing(runstart + runcount - 1));
|
||||
thetally += 2;
|
||||
thecount += runcount;
|
||||
}
|
||||
if (i < 256) {
|
||||
runcount = 1;
|
||||
runchar = xlat[i];
|
||||
runstart = i;
|
||||
}
|
||||
}
|
||||
if (i == 256) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
CHECK_EQ(256, thecount);
|
||||
printf("\t.byte\t%-24s# terminator\n", "0,0");
|
||||
thetally += 2;
|
||||
thebloat = thetally;
|
||||
for (i = 0; (thetally + i) % 8; i += 2) {
|
||||
printf("\t.byte\t%-24s# padding\n", "0,0");
|
||||
thebloat += 2;
|
||||
}
|
||||
|
||||
printf("\t.endobj\t%s.rom,globl\n", symbol);
|
||||
printf("\n");
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
printf("\t.init.start 300,_init_%s\n", symbol);
|
||||
printf("\tcall\trldecode\n");
|
||||
thebloat += 5;
|
||||
int padding = 8 - thetally % 8;
|
||||
if (padding < 8) {
|
||||
if (padding >= 4) {
|
||||
thebloat += 1;
|
||||
printf("\tlodsl\n");
|
||||
padding -= 4;
|
||||
}
|
||||
if (padding >= 2) {
|
||||
thebloat += 2;
|
||||
printf("\tlodsw\n");
|
||||
}
|
||||
}
|
||||
printf("\t.init.end 300,_init_%s\n", symbol);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
printf("\n");
|
||||
printf("//\t%d bytes total (%d%% original size)\n", thebloat,
|
||||
(int)round((double)thebloat / 256 * 100));
|
||||
}
|
|
@ -134,6 +134,7 @@
|
|||
"__builtin_complex"
|
||||
"__builtin_is_constant_evaluated"
|
||||
"__builtin_expect"
|
||||
"__builtin_expect_with_probability"
|
||||
"__builtin_trap"
|
||||
"__builtin_unreachable"
|
||||
"__builtin_assume"
|
||||
|
|
|
@ -55,6 +55,8 @@ FLAGS
|
|||
-f log worker function calls
|
||||
-B only use stronger cryptography
|
||||
-X disable ssl server and client support
|
||||
-J disable non-ssl server and client support
|
||||
-% hasten startup by not generating an rsa key
|
||||
-s increase silence [repeatable]
|
||||
-v increase verbosity [repeatable]
|
||||
-V increase ssl verbosity [repeatable]
|
||||
|
@ -1096,27 +1098,51 @@ FUNCTIONS
|
|||
Defaults to 86400 (24 hours). This may be set to ≤0 to disable
|
||||
SSL tickets. It's a good idea to use these since it increases
|
||||
handshake performance 10x and eliminates a network round trip.
|
||||
This function is not available in unsecure mode.
|
||||
|
||||
EvadeDragnetSurveillance(bool)
|
||||
If this option is programmed then redbean will not transmit a
|
||||
Server Name Indicator (SNI) when performing Fetch() requests.
|
||||
This function is not available in unsecure mode.
|
||||
|
||||
ProgramSslPresharedKey(key:str,identity:str)
|
||||
This function can be used to enable the PSK ciphersuites
|
||||
which simplify SSL and enhance its performance in controlled
|
||||
This function can be used to enable the PSK ciphersuites which
|
||||
simplify SSL and enhance its performance in controlled
|
||||
environments. `key` may contain 1..32 bytes of random binary
|
||||
data and identity is usually a short plaintext string. The
|
||||
first time this function is called, the preshared key will
|
||||
be added to both the client and the server SSL configs. If
|
||||
it's called multiple times, then the remaining keys will be
|
||||
added to the server, which is useful if you want to assign
|
||||
separate keys to each client, each of which needs a separate
|
||||
identity too. If this function is called multiple times with
|
||||
the same identity string, then the latter call will overwrite
|
||||
the prior. If a preshared key is supplied and no certificates
|
||||
or key-signing-keys are programmed, then redbean won't bother
|
||||
first time this function is called, the preshared key will be
|
||||
added to both the client and the server SSL configs. If it's
|
||||
called multiple times, then the remaining keys will be added
|
||||
to the server, which is useful if you want to assign separate
|
||||
keys to each client, each of which needs a separate identity
|
||||
too. If this function is called multiple times with the same
|
||||
identity string, then the latter call will overwrite the
|
||||
prior. If a preshared key is supplied and no certificates or
|
||||
key-signing-keys are programmed, then redbean won't bother
|
||||
auto-generating any serving certificates and will instead use
|
||||
only PSK ciphersuites.
|
||||
only PSK ciphersuites. This function is not available in
|
||||
unsecure mode.
|
||||
|
||||
ProgramSslFetchVerify(enabled:str)
|
||||
May be used to disable the the verification of certificates
|
||||
for remote hosts when using the Fetch() API. This function is
|
||||
not available in unsecure mode.
|
||||
|
||||
ProgramSslClientVerify(enabled:str)
|
||||
Enables the verification of certificates supplied by the HTTP
|
||||
clients that connect to your redbean. This has the same effect
|
||||
as the `-j` flag. Tuning this option alone does not preclude
|
||||
the possibility of unsecured HTTP clients, which can be
|
||||
disabled using ProgramSslRequired(). This function can only be
|
||||
called from `.init.lua`. This function is not available in
|
||||
unsecure mode.
|
||||
|
||||
ProgramSslRequired(mandatory:str)
|
||||
Enables the blocking of HTTP so that all inbound clients and
|
||||
must use the TLS transport layer. This has the same effect as
|
||||
the `-J` flag. Fetch() is still allowed to make outbound HTTP
|
||||
requests. This function can only be called from `.init.lua`.
|
||||
This function is not available in unsecure mode.
|
||||
|
||||
ProgramSslCiphersuite(name:str)
|
||||
See https://redbean.dev/ for further details.
|
||||
|
|
|
@ -158,7 +158,7 @@ int LuaDecimate(lua_State *L) {
|
|||
unsigned char *p;
|
||||
s = luaL_checklstring(L, 1, &n);
|
||||
m = ROUNDUP(n, 16);
|
||||
CHECK_NOTNULL((p = LuaAlloc(L, m)));
|
||||
p = LuaAllocOrDie(L, m);
|
||||
bzero(p + n, m - n);
|
||||
cDecimate2xUint8x8(m, p, (signed char[8]){-1, -3, 3, 17, 17, 3, -3, -1});
|
||||
lua_pushlstring(L, (char *)p, (n + 1) >> 1);
|
||||
|
@ -408,7 +408,7 @@ int LuaGetRandomBytes(lua_State *L) {
|
|||
luaL_argerror(L, 1, "not in range 1..256");
|
||||
unreachable;
|
||||
}
|
||||
CHECK_NOTNULL((p = LuaAlloc(L, n)));
|
||||
p = LuaAllocOrDie(L, n);
|
||||
CHECK_EQ(n, getrandom(p, n, 0));
|
||||
lua_pushlstring(L, p, n);
|
||||
free(p);
|
||||
|
@ -648,7 +648,8 @@ int LuaBenchmark(lua_State *L) {
|
|||
if (TSC_AUX_CORE(Rdpid()) == core && GetInterrupts() == interrupts) {
|
||||
break;
|
||||
} else if (attempts >= maxattempts) {
|
||||
return luaL_error(L, "system is under too much load to run benchmark");
|
||||
luaL_error(L, "system is under too much load to run benchmark");
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
overhead = avgticks;
|
||||
|
@ -669,7 +670,8 @@ int LuaBenchmark(lua_State *L) {
|
|||
if (TSC_AUX_CORE(Rdpid()) == core && GetInterrupts() == interrupts) {
|
||||
break;
|
||||
} else if (attempts >= maxattempts) {
|
||||
return luaL_error(L, "system is under too much load to run benchmark");
|
||||
luaL_error(L, "system is under too much load to run benchmark");
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
avgticks = MAX(avgticks - overhead, 0);
|
||||
|
@ -682,7 +684,24 @@ int LuaBenchmark(lua_State *L) {
|
|||
return 4;
|
||||
}
|
||||
|
||||
static void LuaCompress2(lua_State *L, void *dest, size_t *destLen,
|
||||
const void *source, size_t sourceLen, int level) {
|
||||
switch (compress2(dest, destLen, source, sourceLen, level)) {
|
||||
case Z_OK:
|
||||
break;
|
||||
case Z_BUF_ERROR:
|
||||
luaL_error(L, "out of memory");
|
||||
unreachable;
|
||||
case Z_STREAM_ERROR:
|
||||
luaL_error(L, "invalid level");
|
||||
unreachable;
|
||||
default:
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
int LuaCompress(lua_State *L) {
|
||||
int rc;
|
||||
bool raw;
|
||||
size_t n, m;
|
||||
char *q, *e;
|
||||
|
@ -694,19 +713,17 @@ int LuaCompress(lua_State *L) {
|
|||
m = compressBound(n);
|
||||
if (lua_toboolean(L, 3)) {
|
||||
// raw mode
|
||||
CHECK_NOTNULL((q = LuaAlloc(L, m)));
|
||||
CHECK_EQ(Z_OK,
|
||||
compress2((unsigned char *)q, &m, (unsigned char *)p, n, level));
|
||||
q = LuaAllocOrDie(L, m);
|
||||
LuaCompress2(L, q, &m, p, n, level);
|
||||
lua_pushlstring(L, q, m);
|
||||
} else {
|
||||
// easy mode
|
||||
CHECK_NOTNULL((q = LuaAlloc(L, 10 + 4 + m)));
|
||||
q = LuaAllocOrDie(L, 10 + 4 + m);
|
||||
crc = crc32_z(0, p, n);
|
||||
e = uleb64(q, n);
|
||||
e = WRITE32LE(e, crc);
|
||||
hdrlen = e - q;
|
||||
CHECK_EQ(Z_OK, compress2((unsigned char *)(q + hdrlen), &m,
|
||||
(unsigned char *)p, n, level));
|
||||
LuaCompress2(L, q + hdrlen, &m, p, n, level);
|
||||
lua_pushlstring(L, q, hdrlen + m);
|
||||
}
|
||||
free(q);
|
||||
|
@ -727,7 +744,7 @@ int LuaUncompress(lua_State *L) {
|
|||
}
|
||||
len = m;
|
||||
crc = READ32LE(p + rc);
|
||||
CHECK_NOTNULL((q = LuaAlloc(L, m)));
|
||||
q = LuaAllocOrDie(L, m);
|
||||
if (uncompress((void *)q, &m, (unsigned char *)p + rc + 4, n) != Z_OK ||
|
||||
m != len || crc32_z(0, q, m) != crc) {
|
||||
free(q);
|
||||
|
@ -736,7 +753,7 @@ int LuaUncompress(lua_State *L) {
|
|||
}
|
||||
} else {
|
||||
len = m = luaL_checkinteger(L, 2);
|
||||
CHECK_NOTNULL((q = LuaAlloc(L, m)));
|
||||
q = LuaAllocOrDie(L, m);
|
||||
if (uncompress((void *)q, &m, (void *)p, n) != Z_OK || m != len) {
|
||||
free(q);
|
||||
luaL_error(L, "compressed value is corrupted");
|
||||
|
|
|
@ -13,6 +13,7 @@ int luaopen_lsqlite3(lua_State *);
|
|||
|
||||
void *LuaRealloc(lua_State *, void *, size_t);
|
||||
void *LuaAlloc(lua_State *, size_t);
|
||||
void *LuaAllocOrDie(lua_State *, size_t);
|
||||
|
||||
int LuaBenchmark(lua_State *);
|
||||
int LuaBin(lua_State *);
|
||||
|
|
119
tool/net/lunix.c
119
tool/net/lunix.c
|
@ -120,6 +120,16 @@ void *LuaAlloc(lua_State *L, size_t n) {
|
|||
return LuaRealloc(L, 0, n);
|
||||
}
|
||||
|
||||
void *LuaAllocOrDie(lua_State *L, size_t n) {
|
||||
void *p;
|
||||
if ((p = LuaAlloc(L, n))) {
|
||||
return p;
|
||||
} else {
|
||||
luaL_error(L, "out of memory");
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
static lua_Integer FixLimit(long x) {
|
||||
if (0 <= x && x < RLIM_INFINITY) {
|
||||
return x;
|
||||
|
@ -434,19 +444,18 @@ static int LuaUnixReadlink(lua_State *L) {
|
|||
size_t got, bufsiz = 8192;
|
||||
path = luaL_checkstring(L, 1);
|
||||
dirfd = luaL_optinteger(L, 2, AT_FDCWD);
|
||||
if ((buf = LuaAlloc(L, bufsiz))) {
|
||||
if ((rc = readlinkat(dirfd, path, buf, bufsiz)) != -1) {
|
||||
got = rc;
|
||||
if (got < bufsiz) {
|
||||
lua_pushlstring(L, buf, got);
|
||||
free(buf);
|
||||
return 1;
|
||||
} else {
|
||||
enametoolong();
|
||||
}
|
||||
buf = LuaAllocOrDie(L, bufsiz);
|
||||
if ((rc = readlinkat(dirfd, path, buf, bufsiz)) != -1) {
|
||||
got = rc;
|
||||
if (got < bufsiz) {
|
||||
lua_pushlstring(L, buf, got);
|
||||
free(buf);
|
||||
return 1;
|
||||
} else {
|
||||
enametoolong();
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
free(buf);
|
||||
return SysretErrno(L, "readlink", olderr);
|
||||
}
|
||||
|
||||
|
@ -535,16 +544,13 @@ static int LuaUnixCommandv(lua_State *L) {
|
|||
char *pathbuf, *resolved;
|
||||
olderr = errno;
|
||||
prog = luaL_checkstring(L, 1);
|
||||
if ((pathbuf = LuaAlloc(L, PATH_MAX))) {
|
||||
if ((resolved = commandv(prog, pathbuf, PATH_MAX))) {
|
||||
lua_pushstring(L, resolved);
|
||||
free(pathbuf);
|
||||
return 1;
|
||||
} else {
|
||||
free(pathbuf);
|
||||
return SysretErrno(L, "commandv", olderr);
|
||||
}
|
||||
pathbuf = LuaAllocOrDie(L, PATH_MAX);
|
||||
if ((resolved = commandv(prog, pathbuf, PATH_MAX))) {
|
||||
lua_pushstring(L, resolved);
|
||||
free(pathbuf);
|
||||
return 1;
|
||||
} else {
|
||||
free(pathbuf);
|
||||
return SysretErrno(L, "commandv", olderr);
|
||||
}
|
||||
}
|
||||
|
@ -905,22 +911,19 @@ static int LuaUnixRead(lua_State *L) {
|
|||
bufsiz = luaL_optinteger(L, 2, BUFSIZ);
|
||||
offset = luaL_optinteger(L, 3, -1);
|
||||
bufsiz = MIN(bufsiz, 0x7ffff000);
|
||||
if ((buf = LuaAlloc(L, bufsiz))) {
|
||||
if (offset == -1) {
|
||||
rc = read(fd, buf, bufsiz);
|
||||
} else {
|
||||
rc = pread(fd, buf, bufsiz, offset);
|
||||
}
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
lua_pushlstring(L, buf, got);
|
||||
free(buf);
|
||||
return 1;
|
||||
} else {
|
||||
free(buf);
|
||||
return SysretErrno(L, "read", olderr);
|
||||
}
|
||||
buf = LuaAllocOrDie(L, bufsiz);
|
||||
if (offset == -1) {
|
||||
rc = read(fd, buf, bufsiz);
|
||||
} else {
|
||||
rc = pread(fd, buf, bufsiz, offset);
|
||||
}
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
lua_pushlstring(L, buf, got);
|
||||
free(buf);
|
||||
return 1;
|
||||
} else {
|
||||
free(buf);
|
||||
return SysretErrno(L, "read", olderr);
|
||||
}
|
||||
}
|
||||
|
@ -1238,9 +1241,7 @@ static int LuaUnixSiocgifconf(lua_State *L) {
|
|||
struct ifreq *ifr;
|
||||
struct ifconf conf;
|
||||
olderr = errno;
|
||||
if (!(data = LuaAlloc(L, (n = 4096)))) {
|
||||
return SysretErrno(L, "siocgifconf", olderr);
|
||||
}
|
||||
data = LuaAllocOrDie(L, (n = 4096));
|
||||
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) == -1) {
|
||||
free(data);
|
||||
return SysretErrno(L, "siocgifconf", olderr);
|
||||
|
@ -1384,20 +1385,17 @@ static int LuaUnixRecvfrom(lua_State *L) {
|
|||
bufsiz = luaL_optinteger(L, 2, 1500);
|
||||
bufsiz = MIN(bufsiz, 0x7ffff000);
|
||||
flags = luaL_optinteger(L, 3, 0);
|
||||
if ((buf = LuaAlloc(L, bufsiz))) {
|
||||
rc = recvfrom(fd, buf, bufsiz, flags, &sa, &addrsize);
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
lua_pushlstring(L, buf, got);
|
||||
lua_pushinteger(L, ntohl(sa.sin_addr.s_addr));
|
||||
lua_pushinteger(L, ntohs(sa.sin_port));
|
||||
free(buf);
|
||||
return 3;
|
||||
} else {
|
||||
free(buf);
|
||||
return SysretErrno(L, "recvfrom", olderr);
|
||||
}
|
||||
buf = LuaAllocOrDie(L, bufsiz);
|
||||
rc = recvfrom(fd, buf, bufsiz, flags, &sa, &addrsize);
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
lua_pushlstring(L, buf, got);
|
||||
lua_pushinteger(L, ntohl(sa.sin_addr.s_addr));
|
||||
lua_pushinteger(L, ntohs(sa.sin_port));
|
||||
free(buf);
|
||||
return 3;
|
||||
} else {
|
||||
free(buf);
|
||||
return SysretErrno(L, "recvfrom", olderr);
|
||||
}
|
||||
}
|
||||
|
@ -1415,18 +1413,15 @@ static int LuaUnixRecv(lua_State *L) {
|
|||
bufsiz = luaL_optinteger(L, 2, 1500);
|
||||
bufsiz = MIN(bufsiz, 0x7ffff000);
|
||||
flags = luaL_optinteger(L, 3, 0);
|
||||
if ((buf = LuaAlloc(L, bufsiz))) {
|
||||
rc = recv(fd, buf, bufsiz, flags);
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
lua_pushlstring(L, buf, got);
|
||||
free(buf);
|
||||
return 1;
|
||||
} else {
|
||||
free(buf);
|
||||
return SysretErrno(L, "recv", olderr);
|
||||
}
|
||||
buf = LuaAllocOrDie(L, bufsiz);
|
||||
rc = recv(fd, buf, bufsiz, flags);
|
||||
if (rc != -1) {
|
||||
got = rc;
|
||||
lua_pushlstring(L, buf, got);
|
||||
free(buf);
|
||||
return 1;
|
||||
} else {
|
||||
free(buf);
|
||||
return SysretErrno(L, "recv", olderr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,10 +115,10 @@ o/$(MODE)/tool/net/redbean.com: \
|
|||
tool/net/redbean.png
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -AMKDIR -T$@ $(MKDIR) o/$(MODE)/tool/net/.redbean
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com -o o/$(MODE)/tool/net/.redbean/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean/.symtab
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/net/.redbean/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean/.symtab \
|
||||
tool/net/help.txt \
|
||||
tool/net/.init.lua \
|
||||
tool/net/favicon.ico \
|
||||
|
@ -260,9 +260,8 @@ o/$(MODE)/tool/net/redbean-demo.com: \
|
|||
@$(COMPILE) -AMKDIR -T$@ $(MKDIR) o/$(MODE)/tool/net/.redbean-demo
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/net/.redbean-demo/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean-demo/.symtab
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean-demo/.symtab \
|
||||
tool/net/help.txt
|
||||
|
||||
# REDBEAN-STATIC.COM
|
||||
|
@ -281,9 +280,8 @@ o/$(MODE)/tool/net/redbean-static.com: \
|
|||
@$(COMPILE) -AMKDIR -T$@ $(MKDIR) o/$(MODE)/tool/net/.redbean-static
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/net/.redbean-static/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean-static/.symtab
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean-static/.symtab \
|
||||
tool/net/help.txt \
|
||||
tool/net/favicon.ico \
|
||||
tool/net/redbean.png
|
||||
|
@ -316,9 +314,8 @@ o/$(MODE)/tool/net/redbean-unsecure.com: \
|
|||
@$(COMPILE) -AMKDIR -T$@ $(MKDIR) o/$(MODE)/tool/net/.redbean-unsecure
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/net/.redbean-unsecure/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean-unsecure/.symtab
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean-unsecure/.symtab \
|
||||
tool/net/help.txt \
|
||||
tool/net/favicon.ico \
|
||||
tool/net/redbean.png
|
||||
|
@ -331,6 +328,7 @@ o/$(MODE)/tool/net/redbean-unsecure.com.dbg: \
|
|||
o/$(MODE)/tool/net/lunix.o \
|
||||
o/$(MODE)/tool/net/lmaxmind.o \
|
||||
o/$(MODE)/tool/net/lsqlite3.o \
|
||||
o/$(MODE)/tool/net/largon2.o \
|
||||
o/$(MODE)/tool/net/net.pkg \
|
||||
$(CRT) \
|
||||
$(APE_NO_MODIFY_SELF)
|
||||
|
@ -358,9 +356,8 @@ o/$(MODE)/tool/net/redbean-original.com: \
|
|||
@$(COMPILE) -AMKDIR -T$@ $(MKDIR) o/$(MODE)/tool/net/.redbean-original
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/net/.redbean-original/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean-original/.symtab
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/net/.redbean-original/.symtab \
|
||||
tool/net/help.txt \
|
||||
tool/net/favicon.ico \
|
||||
tool/net/redbean.png
|
||||
|
|
|
@ -34,9 +34,11 @@
|
|||
#include "libc/dos.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/nomultics.internal.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
|
@ -51,13 +53,13 @@
|
|||
#include "libc/runtime/clktck.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/sock/goodsocket.internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/append.internal.h"
|
||||
#include "libc/stdio/hex.internal.h"
|
||||
#include "libc/str/slice.h"
|
||||
#include "libc/str/undeflate.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/clone.h"
|
||||
#include "libc/sysv/consts/dt.h"
|
||||
|
@ -66,6 +68,7 @@
|
|||
#include "libc/sysv/consts/f.h"
|
||||
#include "libc/sysv/consts/inaddr.h"
|
||||
#include "libc/sysv/consts/ipproto.h"
|
||||
#include "libc/sysv/consts/madv.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
|
@ -164,12 +167,10 @@ STATIC_YOINK("zip_uri_support");
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
// letters not used: EIJNOQYnoqwxy
|
||||
// letters not used: EINOQYnoqwxy
|
||||
// digits not used: 0123456789
|
||||
// puncts not used: !"#$%&'()*+,-./;<=>@[\]^_`{|}~
|
||||
#define GETOPTS "BSVXZabdfghijkmsuvzA:C:D:F:G:H:K:L:M:P:R:T:U:W:c:e:l:p:r:t:"
|
||||
|
||||
extern unsigned long long __kbirth;
|
||||
// puncts not used: !"#$&'()*+,-./;<=>@[\]^_`{|}~
|
||||
#define GETOPTS "%BJSVXZabdfghijkmsuvzA:C:D:F:G:H:K:L:M:P:R:T:U:W:c:e:l:p:r:t:"
|
||||
|
||||
static const uint8_t kGzipHeader[] = {
|
||||
0x1F, // MAGNUM
|
||||
|
@ -329,21 +330,23 @@ static const char kCounterNames[] =
|
|||
typedef ssize_t (*reader_f)(int, void *, size_t);
|
||||
typedef ssize_t (*writer_f)(int, struct iovec *, int);
|
||||
|
||||
static bool usessl;
|
||||
static bool suiteb;
|
||||
static bool killed;
|
||||
static bool istext;
|
||||
static bool zombied;
|
||||
static bool gzipped;
|
||||
static bool branded;
|
||||
static bool usingssl;
|
||||
static bool funtrace;
|
||||
static bool systrace;
|
||||
static bool meltdown;
|
||||
static bool unsecure;
|
||||
static bool norsagen;
|
||||
static bool printport;
|
||||
static bool daemonize;
|
||||
static bool logrusage;
|
||||
static bool logbodies;
|
||||
static bool requiressl;
|
||||
static bool isterminal;
|
||||
static bool sslcliused;
|
||||
static bool loglatency;
|
||||
|
@ -1459,7 +1462,7 @@ static ssize_t SslWrite(int fd, struct iovec *iov, int iovlen) {
|
|||
|
||||
static void NotifyClose(void) {
|
||||
#ifndef UNSECURE
|
||||
if (usessl) {
|
||||
if (usingssl) {
|
||||
DEBUGF("(ssl) SSL notifying close");
|
||||
mbedtls_ssl_close_notify(&ssl);
|
||||
}
|
||||
|
@ -1615,7 +1618,7 @@ static bool TlsSetup(void) {
|
|||
if (!(r = mbedtls_ssl_handshake(&ssl)) && TlsFlush(&g_bio, 0, 0) != -1) {
|
||||
LockInc(&shared->c.sslhandshakes);
|
||||
g_bio.c = -1;
|
||||
usessl = true;
|
||||
usingssl = true;
|
||||
reader = SslRead;
|
||||
writer = SslWrite;
|
||||
WipeServingKeys();
|
||||
|
@ -1855,14 +1858,20 @@ static void LoadCertificates(void) {
|
|||
#ifdef MBEDTLS_ECP_C
|
||||
ecp = GenerateEcpCertificate(ksk.key ? &ksk : 0);
|
||||
if (!havecert) UseCertificate(&conf, &ecp, "server");
|
||||
if (!haveclientcert && ksk.key) UseCertificate(&confcli, &ecp, "client");
|
||||
if (!haveclientcert && ksk.key) {
|
||||
UseCertificate(&confcli, &ecp, "client");
|
||||
}
|
||||
AppendCert(ecp.cert, ecp.key);
|
||||
#endif
|
||||
#ifdef MBEDTLS_RSA_C
|
||||
rsa = GenerateRsaCertificate(ksk.key ? &ksk : 0);
|
||||
if (!havecert) UseCertificate(&conf, &rsa, "server");
|
||||
if (!haveclientcert && ksk.key) UseCertificate(&confcli, &rsa, "client");
|
||||
AppendCert(rsa.cert, rsa.key);
|
||||
if (!norsagen) {
|
||||
rsa = GenerateRsaCertificate(ksk.key ? &ksk : 0);
|
||||
if (!havecert) UseCertificate(&conf, &rsa, "server");
|
||||
if (!haveclientcert && ksk.key) {
|
||||
UseCertificate(&confcli, &rsa, "client");
|
||||
}
|
||||
AppendCert(rsa.cert, rsa.key);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
WipeSigningKeys();
|
||||
|
@ -2138,43 +2147,8 @@ static char *AppendContentRange(char *p, long a, long b, long c) {
|
|||
}
|
||||
|
||||
static bool Inflate(void *dp, size_t dn, const void *sp, size_t sn) {
|
||||
int rc;
|
||||
z_stream zs;
|
||||
struct DeflateState ds;
|
||||
LockInc(&shared->c.inflates);
|
||||
if (IsTiny()) {
|
||||
return undeflate(dp, dn, sp, sn, &ds) != -1;
|
||||
} else {
|
||||
zs.zfree = 0;
|
||||
zs.zalloc = 0;
|
||||
zs.next_in = sp;
|
||||
zs.avail_in = sn;
|
||||
zs.total_in = sn;
|
||||
zs.next_out = dp;
|
||||
zs.avail_out = dn;
|
||||
zs.total_out = dn;
|
||||
CHECK_EQ(Z_OK, inflateInit2(&zs, -MAX_WBITS));
|
||||
switch ((rc = inflate(&zs, Z_NO_FLUSH))) {
|
||||
case Z_STREAM_END:
|
||||
CHECK_EQ(Z_OK, inflateEnd(&zs));
|
||||
return true;
|
||||
case Z_DATA_ERROR:
|
||||
inflateEnd(&zs);
|
||||
WARNF("(zip) Z_DATA_ERROR: %s", zs.msg);
|
||||
return false;
|
||||
case Z_NEED_DICT:
|
||||
inflateEnd(&zs);
|
||||
WARNF("(zip) Z_NEED_DICT");
|
||||
return false;
|
||||
case Z_MEM_ERROR:
|
||||
DIEF("(zip) Z_MEM_ERROR");
|
||||
default:
|
||||
DIEF("(zip) inflate()→%d dn=%ld sn=%ld "
|
||||
"next_in=%ld avail_in=%ld next_out=%ld avail_out=%ld",
|
||||
rc, dn, sn, (char *)zs.next_in - (char *)sp, zs.avail_in,
|
||||
(char *)zs.next_out - (char *)dp, zs.avail_out);
|
||||
}
|
||||
}
|
||||
return !__inflate(dp, dn, sp, sn);
|
||||
}
|
||||
|
||||
static bool Verify(void *data, size_t size, uint32_t crc) {
|
||||
|
@ -2288,7 +2262,7 @@ static ssize_t Send(struct iovec *iov, int iovlen) {
|
|||
}
|
||||
|
||||
static bool IsSslCompressed(void) {
|
||||
return usessl && ssl.session->compression;
|
||||
return usingssl && ssl.session->compression;
|
||||
}
|
||||
|
||||
static char *CommitOutput(char *p) {
|
||||
|
@ -2525,7 +2499,7 @@ static char *ServeAssetCompressed(struct Asset *a) {
|
|||
dg.t = 0;
|
||||
dg.i = 0;
|
||||
dg.c = 0;
|
||||
if (usessl) {
|
||||
if (usingssl) {
|
||||
dg.z = 512 + (rand64() & 1023);
|
||||
} else {
|
||||
dg.z = 65536;
|
||||
|
@ -3333,7 +3307,7 @@ static int LuaGetStatus(lua_State *L) {
|
|||
static int LuaGetSslIdentity(lua_State *L) {
|
||||
const mbedtls_x509_crt *cert;
|
||||
OnlyCallDuringRequest(L, "GetSslIdentity");
|
||||
if (!usessl) {
|
||||
if (!usingssl) {
|
||||
lua_pushnil(L);
|
||||
} else {
|
||||
if (sslpskindex) {
|
||||
|
@ -3684,7 +3658,7 @@ static int LuaFetch(lua_State *L) {
|
|||
#define ssl nope // TODO(jart): make this file less huge
|
||||
char *p;
|
||||
ssize_t rc;
|
||||
bool usessl;
|
||||
bool usingssl;
|
||||
uint32_t ip;
|
||||
struct Url url;
|
||||
int t, ret, sock, methodidx, hdridx;
|
||||
|
@ -3785,12 +3759,12 @@ static int LuaFetch(lua_State *L) {
|
|||
*/
|
||||
gc(ParseUrl(urlarg, urlarglen, &url));
|
||||
gc(url.params.p);
|
||||
usessl = false;
|
||||
usingssl = false;
|
||||
if (url.scheme.n) {
|
||||
#ifndef UNSECURE
|
||||
if (!unsecure && url.scheme.n == 5 &&
|
||||
!memcasecmp(url.scheme.p, "https", 5)) {
|
||||
usessl = true;
|
||||
usingssl = true;
|
||||
} else
|
||||
#endif
|
||||
if (!(url.scheme.n == 4 && !memcasecmp(url.scheme.p, "http", 4))) {
|
||||
|
@ -3800,7 +3774,7 @@ static int LuaFetch(lua_State *L) {
|
|||
}
|
||||
|
||||
#ifndef UNSECURE
|
||||
if (usessl && !sslinitialized) TlsInit();
|
||||
if (usingssl && !sslinitialized) TlsInit();
|
||||
#endif
|
||||
|
||||
if (url.host.n) {
|
||||
|
@ -3808,7 +3782,7 @@ static int LuaFetch(lua_State *L) {
|
|||
if (url.port.n) {
|
||||
port = gc(strndup(url.port.p, url.port.n));
|
||||
#ifndef UNSECURE
|
||||
} else if (usessl) {
|
||||
} else if (usingssl) {
|
||||
port = "443";
|
||||
#endif
|
||||
} else {
|
||||
|
@ -3880,7 +3854,7 @@ static int LuaFetch(lua_State *L) {
|
|||
}
|
||||
|
||||
#ifndef UNSECURE
|
||||
if (usessl) {
|
||||
if (usingssl) {
|
||||
if (sslcliused) {
|
||||
mbedtls_ssl_session_reset(&sslcli);
|
||||
} else {
|
||||
|
@ -3921,7 +3895,7 @@ static int LuaFetch(lua_State *L) {
|
|||
*/
|
||||
DEBUGF("(ftch) client sending %s request", method);
|
||||
#ifndef UNSECURE
|
||||
if (usessl) {
|
||||
if (usingssl) {
|
||||
ret = mbedtls_ssl_write(&sslcli, request, requestlen);
|
||||
if (ret != requestlen) {
|
||||
if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) goto VerifyFailed;
|
||||
|
@ -3953,7 +3927,7 @@ static int LuaFetch(lua_State *L) {
|
|||
}
|
||||
NOISEF("(ftch) client reading");
|
||||
#ifndef UNSECURE
|
||||
if (usessl) {
|
||||
if (usingssl) {
|
||||
if ((rc = mbedtls_ssl_read(&sslcli, inbuf.p + inbuf.n,
|
||||
inbuf.c - inbuf.n)) < 0) {
|
||||
if (rc == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
|
||||
|
@ -4457,7 +4431,7 @@ static int LuaSetCookie(lua_State *L) {
|
|||
issecurepref =
|
||||
keylen > strlen(securepref) &&
|
||||
SlicesEqual(key, strlen(securepref), securepref, strlen(securepref));
|
||||
if ((ishostpref || issecurepref) && !usessl) {
|
||||
if ((ishostpref || issecurepref) && !usingssl) {
|
||||
luaL_argerror(
|
||||
L, 1,
|
||||
gc(xasprintf("%s and %s prefixes require SSL", hostpref, securepref)));
|
||||
|
@ -4625,7 +4599,7 @@ static int LuaGetClientFd(lua_State *L) {
|
|||
|
||||
static int LuaIsClientUsingSsl(lua_State *L) {
|
||||
OnlyCallDuringConnection(L, "IsClientUsingSsl");
|
||||
lua_pushboolean(L, usessl);
|
||||
lua_pushboolean(L, usingssl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -4760,6 +4734,11 @@ static int LuaProgramSslClientVerify(lua_State *L) {
|
|||
return LuaProgramBool(L, &sslclientverify);
|
||||
}
|
||||
|
||||
static int LuaProgramSslRequired(lua_State *L) {
|
||||
OnlyCallFromInitLua(L, "ProgramSslRequired");
|
||||
return LuaProgramBool(L, &requiressl);
|
||||
}
|
||||
|
||||
static int LuaProgramSslFetchVerify(lua_State *L) {
|
||||
OnlyCallFromMainProcess(L, "ProgramSslFetchVerify");
|
||||
return LuaProgramBool(L, &sslfetchverify);
|
||||
|
@ -4984,6 +4963,7 @@ static const char *const kDontAutoComplete[] = {
|
|||
"ProgramPrivateKey", // TODO
|
||||
"ProgramSslCiphersuite", // TODO
|
||||
"ProgramSslClientVerify", // TODO
|
||||
"LuaProgramSslRequired", // TODO
|
||||
"ProgramSslCompression", //
|
||||
"ProgramSslTicketLifetime", //
|
||||
"ProgramTimeout", // TODO
|
||||
|
@ -5108,7 +5088,6 @@ static const luaL_Reg kLuaFuncs[] = {
|
|||
{"ProgramAddr", LuaProgramAddr}, //
|
||||
{"ProgramBrand", LuaProgramBrand}, //
|
||||
{"ProgramCache", LuaProgramCache}, //
|
||||
{"ProgramCertificate", LuaProgramCertificate}, //
|
||||
{"ProgramDirectory", LuaProgramDirectory}, //
|
||||
{"ProgramGid", LuaProgramGid}, //
|
||||
{"ProgramHeader", LuaProgramHeader}, //
|
||||
|
@ -5117,7 +5096,6 @@ static const luaL_Reg kLuaFuncs[] = {
|
|||
{"ProgramLogPath", LuaProgramLogPath}, //
|
||||
{"ProgramPidPath", LuaProgramPidPath}, //
|
||||
{"ProgramPort", LuaProgramPort}, //
|
||||
{"ProgramPrivateKey", LuaProgramPrivateKey}, //
|
||||
{"ProgramRedirect", LuaProgramRedirect}, //
|
||||
{"ProgramTimeout", LuaProgramTimeout}, //
|
||||
{"ProgramUid", LuaProgramUid}, //
|
||||
|
@ -5157,12 +5135,15 @@ static const luaL_Reg kLuaFuncs[] = {
|
|||
#ifndef UNSECURE
|
||||
{"EvadeDragnetSurveillance", LuaEvadeDragnetSurveillance}, //
|
||||
{"GetSslIdentity", LuaGetSslIdentity}, //
|
||||
{"ProgramCertificate", LuaProgramCertificate}, //
|
||||
{"ProgramPrivateKey", LuaProgramPrivateKey}, //
|
||||
{"ProgramSslCiphersuite", LuaProgramSslCiphersuite}, //
|
||||
{"ProgramSslClientVerify", LuaProgramSslClientVerify}, //
|
||||
{"ProgramSslCompression", LuaProgramSslCompression}, //
|
||||
{"ProgramSslFetchVerify", LuaProgramSslFetchVerify}, //
|
||||
{"ProgramSslInit", LuaProgramSslInit}, //
|
||||
{"ProgramSslPresharedKey", LuaProgramSslPresharedKey}, //
|
||||
{"ProgramSslRequired", LuaProgramSslRequired}, //
|
||||
{"ProgramSslTicketLifetime", LuaProgramSslTicketLifetime}, //
|
||||
#endif
|
||||
};
|
||||
|
@ -5172,9 +5153,7 @@ static const luaL_Reg kLuaLibs[] = {
|
|||
{"unix", LuaUnix}, //
|
||||
{"maxmind", LuaMaxmind}, //
|
||||
{"lsqlite3", luaopen_lsqlite3}, //
|
||||
#ifndef UNSECURE
|
||||
{"argon2", luaopen_argon2}, //
|
||||
#endif
|
||||
{"argon2", luaopen_argon2}, //
|
||||
};
|
||||
|
||||
static void LuaSetArgv(lua_State *L) {
|
||||
|
@ -5742,7 +5721,7 @@ static void ParseRequestParameters(void) {
|
|||
url.path.n = 1;
|
||||
}
|
||||
if (!url.scheme.n) {
|
||||
if (usessl) {
|
||||
if (usingssl) {
|
||||
url.scheme.p = "https";
|
||||
url.scheme.n = 5;
|
||||
} else {
|
||||
|
@ -6212,6 +6191,7 @@ static bool IsSsl(unsigned char c) {
|
|||
}
|
||||
|
||||
static void HandleMessages(void) {
|
||||
char *p;
|
||||
bool once;
|
||||
ssize_t rc;
|
||||
size_t got;
|
||||
|
@ -6238,6 +6218,9 @@ static void HandleMessages(void) {
|
|||
} else {
|
||||
return;
|
||||
}
|
||||
} else if (requiressl) {
|
||||
INFOF("(clnt) %s didn't send an ssl hello", DescribeClient());
|
||||
return;
|
||||
} else {
|
||||
WipeServingKeys();
|
||||
}
|
||||
|
@ -6629,7 +6612,7 @@ static int HandleConnection(size_t i) {
|
|||
} else {
|
||||
switch ((pid = fork())) {
|
||||
case 0:
|
||||
if (monitortty) {
|
||||
if (!IsTiny() && monitortty) {
|
||||
MonitorMemory();
|
||||
}
|
||||
meltdown = false;
|
||||
|
@ -6680,8 +6663,8 @@ static int HandleConnection(size_t i) {
|
|||
inbuf.c = 0;
|
||||
}
|
||||
#ifndef UNSECURE
|
||||
if (usessl) {
|
||||
usessl = false;
|
||||
if (usingssl) {
|
||||
usingssl = false;
|
||||
reader = read;
|
||||
writer = WritevAll;
|
||||
mbedtls_ssl_session_reset(&ssl);
|
||||
|
@ -7023,7 +7006,7 @@ static void TlsInit(void) {
|
|||
if (unsecure) return;
|
||||
|
||||
if (suiteb && !X86_HAVE(AES)) {
|
||||
WARNF("you're using suite b crypto but don't have aes-ni");
|
||||
WARNF("you're using suite b crypto but you don't have aes-ni");
|
||||
}
|
||||
|
||||
if (!sslinitialized) {
|
||||
|
@ -7130,15 +7113,16 @@ static void GetOpts(int argc, char *argv[]) {
|
|||
CASE('v', ++__log_level);
|
||||
CASE('s', --__log_level);
|
||||
CASE('X', unsecure = true);
|
||||
CASE('%', norsagen = true);
|
||||
CASE('Z', systrace = true);
|
||||
CASE('b', logbodies = true);
|
||||
CASE('z', printport = true);
|
||||
CASE('d', daemonize = true);
|
||||
CASE('a', logrusage = true);
|
||||
CASE('J', requiressl = true);
|
||||
CASE('u', uniprocess = true);
|
||||
CASE('g', loglatency = true);
|
||||
CASE('m', logmessages = true);
|
||||
CASE('W', monitortty = optarg);
|
||||
CASE('l', ProgramAddr(optarg));
|
||||
CASE('H', ProgramHeader(optarg));
|
||||
CASE('L', ProgramLogPath(optarg));
|
||||
|
@ -7153,6 +7137,9 @@ static void GetOpts(int argc, char *argv[]) {
|
|||
CASE('t', ProgramTimeout(ParseInt(optarg)));
|
||||
CASE('h', PrintUsage(1, EXIT_SUCCESS));
|
||||
CASE('M', ProgramMaxPayloadSize(ParseInt(optarg)));
|
||||
#if !IsTiny()
|
||||
CASE('W', monitortty = optarg);
|
||||
#endif
|
||||
#ifndef STATIC
|
||||
CASE('e', LuaEvalCode(optarg));
|
||||
CASE('F', LuaEvalFile(optarg));
|
||||
|
@ -7235,11 +7222,13 @@ void RedBean(int argc, char *argv[]) {
|
|||
inbuf = inbuf_actual;
|
||||
isinitialized = true;
|
||||
CallSimpleHookIfDefined("OnServerStart");
|
||||
if (monitortty && (daemonize || uniprocess)) {
|
||||
monitortty = 0;
|
||||
}
|
||||
if (monitortty) {
|
||||
MonitorMemory();
|
||||
if (!IsTiny()) {
|
||||
if (monitortty && (daemonize || uniprocess)) {
|
||||
monitortty = 0;
|
||||
}
|
||||
if (monitortty) {
|
||||
MonitorMemory();
|
||||
}
|
||||
}
|
||||
#ifdef STATIC
|
||||
EventLoop(HEARTBEAT);
|
||||
|
@ -7265,11 +7254,13 @@ void RedBean(int argc, char *argv[]) {
|
|||
TlsDestroy();
|
||||
MemDestroy();
|
||||
}
|
||||
if (monitortty) {
|
||||
terminatemonitor = true;
|
||||
_spinlock(monitortid);
|
||||
munmap(monitorstack, GetStackSize());
|
||||
free(monitortls);
|
||||
if (!IsTiny()) {
|
||||
if (monitortty) {
|
||||
terminatemonitor = true;
|
||||
_spinlock(monitortid);
|
||||
munmap(monitorstack, GetStackSize());
|
||||
free(monitortls);
|
||||
}
|
||||
}
|
||||
INFOF("(srvr) shutdown complete");
|
||||
}
|
||||
|
|
|
@ -54,8 +54,9 @@ o/$(MODE)/tool/plinko/plinko.com: \
|
|||
tool/plinko/plinko.mk
|
||||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -AMKDIR -T$@ $(MKDIR) o/$(MODE)/tool/plinko/.redbean
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com -o o/$(MODE)/tool/plinko/.plinko/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/plinko/.plinko/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/plinko/.plinko/.symtab
|
||||
|
||||
$(TOOL_PLINKO_OBJS): \
|
||||
|
|
|
@ -46,7 +46,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
// usage report
|
||||
fprintf(stderr, "options used: ");
|
||||
fprintf(stderr, "// options used: ");
|
||||
for (j = i = 0; i < 128; ++i) {
|
||||
if (!IsLegal(i)) continue;
|
||||
if (letters_used[i]) {
|
||||
|
@ -56,7 +56,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
if (!j) fprintf(stderr, "none");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "letters not used: ");
|
||||
fprintf(stderr, "// letters not used: ");
|
||||
for (j = i = 0; i < 128; ++i) {
|
||||
if (!isalpha(i)) continue;
|
||||
if (!letters_used[i]) {
|
||||
|
@ -66,7 +66,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
if (!j) fprintf(stderr, "none");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "digits not used: ");
|
||||
fprintf(stderr, "// digits not used: ");
|
||||
for (j = i = 0; i < 128; ++i) {
|
||||
if (!isdigit(i)) continue;
|
||||
if (!letters_used[i]) {
|
||||
|
@ -76,7 +76,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
if (!j) fprintf(stderr, "none");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "puncts not used: ");
|
||||
fprintf(stderr, "// puncts not used: ");
|
||||
for (j = i = 0; i < 128; ++i) {
|
||||
if (!IsLegal(i)) continue;
|
||||
if (isalnum(i)) continue;
|
||||
|
@ -87,7 +87,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
if (!j) fprintf(stderr, "none");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "letters duplicated: ");
|
||||
fprintf(stderr, "// letters duplicated: ");
|
||||
for (j = i = 0; i < 128; ++i) {
|
||||
if (!IsLegal(i)) continue;
|
||||
if (letters_used[i] > 1) {
|
||||
|
@ -100,7 +100,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
// generated code
|
||||
hasargless = false;
|
||||
printf("\n#define GETOPTS \"");
|
||||
printf("#define GETOPTS \"");
|
||||
for (j = i = 0; i < 128; ++i) {
|
||||
if (!IsLegal(i)) continue;
|
||||
if (letters_used[i] && !letters_with_args[i]) {
|
||||
|
@ -131,13 +131,13 @@ int main(int argc, char *argv[]) {
|
|||
printf(" ARGS...\\n\\\n");
|
||||
for (j = i = 0; i < 128; ++i) {
|
||||
if (!IsLegal(i)) continue;
|
||||
if (letters_used[i]) {
|
||||
if (letters_used[i] && !letters_with_args[i]) {
|
||||
printf(" -%c the %c option\\n\\\n", i, i);
|
||||
}
|
||||
}
|
||||
for (j = i = 0; i < 128; ++i) {
|
||||
if (!IsLegal(i)) continue;
|
||||
if (letters_used[i]) {
|
||||
if (letters_with_args[i]) {
|
||||
printf(" -%c VAL the %c option\\n\\\n", i, i);
|
||||
}
|
||||
}
|
||||
|
@ -146,24 +146,30 @@ int main(int argc, char *argv[]) {
|
|||
for (i = 0; i < 128; ++i) {
|
||||
if (!IsLegal(i)) continue;
|
||||
if (letters_used[i]) {
|
||||
if (isalpha(i) || i == '_') {
|
||||
printf("int %cflag;\n", i);
|
||||
if (letters_with_args[i]) {
|
||||
printf("const char *");
|
||||
} else {
|
||||
printf("int ");
|
||||
}
|
||||
if (isalnum(i) || i == '_') {
|
||||
printf("g_%cflag;\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n\
|
||||
static void GetOpts(int argc, char *argv[]) {\n\
|
||||
int opt;\n\
|
||||
while ((opt = getopt(argc, argv, GETOPTS)) != -1) {\n\
|
||||
switch (opt) {\n");
|
||||
for (i = 0; i < 128; ++i) {
|
||||
if (!IsLegal(i)) continue;
|
||||
if (letters_used[i]) {
|
||||
printf(" case '%c':\n", i);
|
||||
if (isalpha(i) || i == '_') {
|
||||
printf(" %cflag", i);
|
||||
if (isalnum(i) || i == '_') {
|
||||
printf(" g_%cflag", i);
|
||||
} else {
|
||||
printf(" XXXflag", i);
|
||||
printf(" g_XXXflag", i);
|
||||
}
|
||||
if (letters_with_args[i]) {
|
||||
printf(" = optarg;\n");
|
||||
|
@ -175,14 +181,19 @@ static void GetOpts(int argc, char *argv[]) {\n\
|
|||
}
|
||||
|
||||
printf(" case '?':\n");
|
||||
printf(" write(1, USAGE, strlen(USAGE));\n");
|
||||
printf(" write(1, USAGE, sizeof(USAGE) - 1);\n");
|
||||
printf(" exit(0);\n");
|
||||
printf(" default:\n");
|
||||
printf(" write(2, USAGE, strlen(USAGE));\n");
|
||||
printf(" write(2, USAGE, sizeof(USAGE) - 1);\n");
|
||||
printf(" exit(64);\n");
|
||||
printf(" }\n");
|
||||
printf(" }\n");
|
||||
printf("}\n");
|
||||
printf("\n");
|
||||
|
||||
printf("int main(int argc, char *argv[]) {\n");
|
||||
printf(" GetOpts(argc, argv);\n");
|
||||
printf("}\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ o/$(MODE)/tool/viz/printimage.com: \
|
|||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/viz/.printimage/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/viz/.printimage/.symtab
|
||||
|
||||
o/$(MODE)/tool/viz/printvideo.com: \
|
||||
|
@ -98,7 +98,7 @@ o/$(MODE)/tool/viz/printvideo.com: \
|
|||
@$(COMPILE) -AOBJCOPY -T$@ $(OBJCOPY) -S -O binary $< $@
|
||||
@$(COMPILE) -ASYMTAB o/$(MODE)/tool/build/symtab.com \
|
||||
-o o/$(MODE)/tool/viz/.printvideo/.symtab $<
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -0qj $@ \
|
||||
@$(COMPILE) -AZIP -T$@ o/$(MODE)/third_party/zip/zip.com -9qj $@ \
|
||||
o/$(MODE)/tool/viz/.printvideo/.symtab
|
||||
|
||||
o/$(MODE)/tool/viz/derasterize.o: \
|
||||
|
|
Loading…
Reference in a new issue