Make redbean StoreAsset() work better

- Better UBSAN error messages
- POSIX Advisory Locks polyfills
- Move redbean manual to /.help.txt
- System call memory safety in ASAN mode
- Character classification now does UNICODE
This commit is contained in:
Justine Tunney 2021-05-14 05:36:58 -07:00
parent 919b6fec10
commit 690be544da
228 changed files with 3653 additions and 3015 deletions

View file

@ -21,9 +21,9 @@
/**
* Locates End Of Central Directory record in ZIP file.
*
* The ZIP spec says this header can be anywhere in the last 64kb.
* We search it backwards for the ZIP-64 "PK♠" magic number. If that's
* not found, then we search again for the original "PK♣♠" magnum. The
* The ZIP spec says this header can be anywhere in the last 64kb. We
* search it backwards for the ZIP-64 "PK♠" magic number. If that's not
* found, then we search again for the original "PK♣♠" magnum. The
* caller needs to check the first four bytes of the returned value to
* determine whether to use ZIP_CDIR_xxx() or ZIP_CDIR64_xxx() macros.
*
@ -31,23 +31,25 @@
* @param n is byte size of file
* @return pointer to EOCD64 or EOCD, or NULL if not found
*/
uint8_t *GetZipCdir(const uint8_t *p, size_t n) {
void *GetZipCdir(const uint8_t *p, size_t n) {
size_t i, j;
if (n >= kZipCdirHdrMinSize) {
i = n - kZipCdirHdrMinSize;
do {
if (READ32LE(p + i) == kZipCdir64HdrMagic && IsZipCdir64(p, n, i)) {
return (/*unconst*/ uint8_t *)(p + i);
} else if (READ32LE(p + i) == kZipCdirHdrMagic && IsZipCdir32(p, n, i)) {
j = i;
do {
if (READ32LE(p + j) == kZipCdir64HdrMagic && IsZipCdir64(p, n, j)) {
return (/*unconst*/ uint8_t *)(p + j);
}
} while (j-- && i - j < 64 * 1024);
return (/*unconst*/ uint8_t *)(p + i);
}
} while (i--);
}
i = n - 4;
do {
if (READ32LE(p + i) == kZipCdir64LocatorMagic &&
i + kZipCdir64LocatorSize <= n &&
IsZipCdir64(p, n, ZIP_LOCATE64_OFFSET(p + i))) {
return (void *)(p + ZIP_LOCATE64_OFFSET(p + i));
} else if (READ32LE(p + i) == kZipCdirHdrMagic && IsZipCdir32(p, n, i)) {
j = i;
do {
if (READ32LE(p + j) == kZipCdir64LocatorMagic &&
j + kZipCdir64LocatorSize <= n &&
IsZipCdir64(p, n, ZIP_LOCATE64_OFFSET(p + j))) {
return (void *)(p + ZIP_LOCATE64_OFFSET(p + j));
}
} while (j-- && i - j < 64 * 1024);
return (void *)(p + i);
}
} while (i--);
return NULL;
}

View file

@ -22,7 +22,7 @@
* Returns comment of zip central directory.
*/
void *GetZipCdirComment(const uint8_t *eocd) {
if (READ32LE(eocd) == kZipCdir64HdrMagic) {
if (READ32LE(eocd) == kZipCdir64HdrMagic && ZIP_CDIR64_COMMENTSIZE(eocd)) {
return ZIP_CDIR64_COMMENT(eocd);
} else {
return ZIP_CDIR_COMMENT(eocd);

View file

@ -22,7 +22,7 @@
* Returns comment of zip central directory.
*/
uint64_t GetZipCdirCommentSize(const uint8_t *eocd) {
if (READ32LE(eocd) == kZipCdir64HdrMagic) {
if (READ32LE(eocd) == kZipCdir64HdrMagic && ZIP_CDIR64_COMMENTSIZE(eocd)) {
return ZIP_CDIR64_COMMENTSIZE(eocd);
} else {
return ZIP_CDIR_COMMENTSIZE(eocd);

View file

@ -714,8 +714,7 @@ int iswlower(wint_t c) {
case u'': // LATIN SMALL D W/ HOOK AND TAIL (0x1d91)
case u'': // LATIN SMALL E W/ RETROFLEX HOOK (0x1d92)
case u'': // LATIN SMALL OPEN E W/ RETROFLEX HOOK (0x1d93)
case u'': // LATIN SMALL REVERSED OPEN E W/ RETROFLEX HOOK
// (0x1d94)
case u'': // LATIN SMALL REVERSED OPEN E W/ RETROFLEX HOOK (0x1d94)
case u'': // LATIN SMALL SCHWA W/ RETROFLEX HOOK (0x1d95)
case u'': // LATIN SMALL I W/ RETROFLEX HOOK (0x1d96)
case u'': // LATIN SMALL OPEN O W/ RETROFLEX HOOK (0x1d97)
@ -1219,8 +1218,7 @@ int iswlower(wint_t c) {
case u'': // LATIN SMALL VY (0xa761)
case u'': // LATIN SMALL VISIGOTHIC Z (0xa763)
case u'': // LATIN SMALL THORN W/ STROKE (0xa765)
case u'': // LATIN SMALL THORN W/ STROKE THROUGH DESCENDER
// (0xa767)
case u'': // LATIN SMALL THORN W/ STROKE THROUGH DESCENDER (0xa767)
case u'': // LATIN SMALL VEND (0xa769)
case u'': // LATIN SMALL ET (0xa76b)
case u'': // LATIN SMALL IS (0xa76d)

View file

@ -23,11 +23,16 @@
* Returns true if zip64 end of central directory header seems legit.
*/
bool IsZipCdir64(const uint8_t *p, size_t n, size_t i) {
if (i > n || n - i < kZipCdir64HdrMinSize) return false;
if (i + kZipCdir64HdrMinSize > n) return false;
if (READ32LE(p + i) != kZipCdir64HdrMagic) return false;
if (i + ZIP_CDIR64_HDRSIZE(p + i) > n) return false;
if (ZIP_CDIR64_DISK(p + i) != ZIP_CDIR64_STARTINGDISK(p + i)) return false;
if (ZIP_CDIR64_RECORDSONDISK(p + i) != ZIP_CDIR64_RECORDS(p + i)) {
if (i + ZIP_CDIR64_HDRSIZE(p + i) + kZipCdir64LocatorSize > n) {
return false;
}
if (ZIP_LOCATE64_MAGIC(p + i + ZIP_CDIR64_HDRSIZE(p + i)) !=
kZipCdir64LocatorMagic) {
return false;
}
if (ZIP_LOCATE64_OFFSET(p + i + ZIP_CDIR64_HDRSIZE(p + i)) != i) {
return false;
}
if (ZIP_CDIR64_RECORDS(p + i) * kZipCfileHdrMinSize >

View file

@ -29,19 +29,22 @@
*/
void *memchr(const void *m, int c, size_t n) {
uint64_t v, w;
const unsigned char *p, *pe;
const char *p, *pe;
c &= 255;
v = 0x0101010101010101 * c;
for (p = (const unsigned char *)m, pe = p + n; p + 8 <= pe; p += 8) {
w = (uint64_t)p[7] << 070 | (uint64_t)p[6] << 060 | (uint64_t)p[5] << 050 |
(uint64_t)p[4] << 040 | (uint64_t)p[3] << 030 | (uint64_t)p[2] << 020 |
(uint64_t)p[1] << 010 | (uint64_t)p[0] << 000;
for (p = m, pe = p + n; p + 8 <= pe; p += 8) {
w = (uint64_t)(255 & p[7]) << 070 | (uint64_t)(255 & p[6]) << 060 |
(uint64_t)(255 & p[5]) << 050 | (uint64_t)(255 & p[4]) << 040 |
(uint64_t)(255 & p[3]) << 030 | (uint64_t)(255 & p[2]) << 020 |
(uint64_t)(255 & p[1]) << 010 | (uint64_t)(255 & p[0]) << 000;
if ((w = ~(w ^ v) & ((w ^ v) - 0x0101010101010101) & 0x8080808080808080)) {
return p + ((unsigned)__builtin_ctzll(w) >> 3);
}
}
for (; p < pe; ++p) {
if (*p == c) return p;
if ((*p & 255) == c) {
return p;
}
}
return NULL;
}

View file

@ -17,14 +17,16 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/bits/bits.h"
#include "libc/str/str.h"
noasan static inline const char *strchr_x64(const char *p, uint64_t c) {
static noasan inline const char *strchr_x64(const char *p, uint64_t c) {
unsigned a, b;
uint64_t w, x, y;
for (c *= 0x0101010101010101;; p += 8) {
w = READ64LE(p);
w = (uint64_t)(255 & p[7]) << 070 | (uint64_t)(255 & p[6]) << 060 |
(uint64_t)(255 & p[5]) << 050 | (uint64_t)(255 & p[4]) << 040 |
(uint64_t)(255 & p[3]) << 030 | (uint64_t)(255 & p[2]) << 020 |
(uint64_t)(255 & p[1]) << 010 | (uint64_t)(255 & p[0]) << 000;
if ((x = ~(w ^ c) & ((w ^ c) - 0x0101010101010101) & 0x8080808080808080) |
(y = ~w & (w - 0x0101010101010101) & 0x8080808080808080)) {
if (x) {
@ -57,8 +59,8 @@ noasan static inline const char *strchr_x64(const char *p, uint64_t c) {
*/
char *strchr(const char *s, int c) {
char *r;
for (c &= 0xff; (uintptr_t)s & 7; ++s) {
if ((*s & 0xff) == c) return s;
for (c &= 255; (uintptr_t)s & 7; ++s) {
if ((*s & 255) == c) return s;
if (!*s) return NULL;
}
r = strchr_x64(s, c);

View file

@ -25,7 +25,6 @@
OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/str/str.h"