diff --git a/GNUmakefile b/GNUmakefile index ba31ec3..09438cc 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -100,6 +100,8 @@ $(MULT_OBJS): uint64.h uint32.h uint16.h safemult.h $(IO_OBJS): uint64.h array.h io.h io_internal.h taia.h tai.h haveepoll.h havekqueue.h havesigio.h havebsdsf.h havedevpoll.h havesendfile.h $(CDB_OBJS): cdb.h uint32.h +mult64.o: haveuint128.h + iob_addbuf.o iob_addfile.o iob_new.o iob_reset.o iob_send.o: iob_internal.h iob.h diff --git a/array/iarray_allocate.c b/array/iarray_allocate.c index bddd53b..2dd58f3 100644 --- a/array/iarray_allocate.c +++ b/array/iarray_allocate.c @@ -11,7 +11,11 @@ #endif static iarray_page* new_page(size_t pagesize) { +#ifdef __MINGW32__ + void* x=malloc(pagesize); +#else void* x=mmap(0,pagesize,PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_PRIVATE,-1,0); +#endif if (x==MAP_FAILED) return 0; return (iarray_page*)x; } @@ -41,7 +45,12 @@ void* iarray_allocate(iarray* ia,size_t pos) { break; p=&(*p)->next; } - if (newpage) munmap(newpage,ia->bytesperpage); + if (newpage) +#ifdef __MINGW32__ + free(newpage); +#else + munmap(newpage,ia->bytesperpage); +#endif { size_t l; do { diff --git a/array/iarray_free.c b/array/iarray_free.c index f742316..4db4198 100644 --- a/array/iarray_free.c +++ b/array/iarray_free.c @@ -1,12 +1,18 @@ #include +#ifndef __MINGW32__ #include +#endif #include #include "iarray.h" static void freechain(iarray_page* p,size_t pagesize) { while (p) { iarray_page* n=p->next; +#ifdef __MINGW32__ + free(p); +#else munmap(p,pagesize); +#endif p=n; } } diff --git a/mult/umult64.c b/mult/umult64.c index db72ee2..3c53f51 100644 --- a/mult/umult64.c +++ b/mult/umult64.c @@ -1,3 +1,5 @@ +#include "haveuint128.h" + #if defined(__x86_64__) && defined(__OPTIMIZE__) /* WARNING: this only works if compiled with -fomit-frame-pointer */ @@ -21,7 +23,7 @@ void umult64() { #include "safemult.h" -#if defined(__GNUC__) && (defined(__x86_64__) || defined(__ia64__) || defined(__powerpc64__) || defined(__alpha__) || defined(__mips64__) || defined(__sparc64__)) +#if defined(HAVE_UINT128) int umult64(uint64 a,uint64 b,uint64* c) { __uint128_t x=((__uint128_t)a)*b; diff --git a/scan/scan_8int.c b/scan/scan_8int.c index 5aa7344..41958d5 100644 --- a/scan/scan_8int.c +++ b/scan/scan_8int.c @@ -1,10 +1,18 @@ #include "scan.h" size_t scan_8int(const char* src,unsigned int* dest) { + /* make a copy of src so we can return the number of bytes we progressed */ register const char *tmp=src; register unsigned int l=0; register unsigned char c; + /* *tmp - '0' can be negative, but casting to unsigned char makes + * those cases positive and large; that means we only need one + * comparison. This trick is no longer needed on modern compilers, + * but we also want to produce good code on old compilers :) */ while ((c=(unsigned char)(*tmp-'0'))<8) { + /* overflow check; for each digit we multiply by 8 and then add the + * digit; 0-7 needs 3 bits of storage, so we need to check if the + * uppermost 3 bits of l are empty. Do it by shifting to the right */ if (l>>(sizeof(l)*8-3)) break; l=l*8+c; ++tmp; diff --git a/scan/scan_8longlong.c b/scan/scan_8longlong.c index 5e660fc..3757a17 100644 --- a/scan/scan_8longlong.c +++ b/scan/scan_8longlong.c @@ -1,10 +1,18 @@ #include "scan.h" size_t scan_8longlong(const char *src,unsigned long long *dest) { + /* make a copy of src so we can return the number of bytes we progressed */ register const char *tmp=src; register unsigned long long l=0; register unsigned char c; + /* *tmp - '0' can be negative, but casting to unsigned char makes + * those cases positive and large; that means we only need one + * comparison. This trick is no longer needed on modern compilers, + * but we also want to produce good code on old compilers :) */ while ((c=(unsigned char)(*tmp-'0'))<8) { + /* overflow check; for each digit we multiply by 8 and then add the + * digit; 0-7 needs 3 bits of storage, so we need to check if the + * uppermost 3 bits of l are empty. Do it by shifting to the right */ if (l>>(sizeof(l)*8-3)) break; l=l*8+c; ++tmp; diff --git a/scan/scan_8longn.c b/scan/scan_8longn.c index 1d51c14..31156fe 100644 --- a/scan/scan_8longn.c +++ b/scan/scan_8longn.c @@ -1,10 +1,18 @@ #include "scan.h" size_t scan_8longn(const char *src,size_t n,unsigned long *dest) { + /* make a copy of src so we can return the number of bytes we progressed */ register const char *tmp=src; register unsigned long l=0; register unsigned char c; + /* *tmp - '0' can be negative, but casting to unsigned char makes + * those cases positive and large; that means we only need one + * comparison. This trick is no longer needed on modern compilers, + * but we also want to produce good code on old compilers :) */ while (n-->0 && (c=(unsigned char)(*tmp-'0'))<8) { + /* overflow check; for each digit we multiply by 8 and then add the + * digit; 0-7 needs 3 bits of storage, so we need to check if the + * uppermost 3 bits of l are empty. Do it by shifting to the right */ if (l>>(sizeof(l)*8-3)) break; l=l*8+c; ++tmp; diff --git a/scan/scan_8short.c b/scan/scan_8short.c index c723b2b..557087c 100644 --- a/scan/scan_8short.c +++ b/scan/scan_8short.c @@ -1,10 +1,20 @@ #include "scan.h" size_t scan_8short(const char* src,unsigned short* dest) { + /* make a copy of src so we can return the number of bytes we progressed */ register const char *tmp=src; + /* this is called l because we copy and pasted from 8long, where l + * stood for "long" */ register unsigned short l=0; register unsigned char c; + /* *tmp - '0' can be negative, but casting to unsigned char makes + * those cases positive and large; that means we only need one + * comparison. This trick is no longer needed on modern compilers, + * but we also want to produce good code on old compilers :) */ while ((c=(unsigned char)(*tmp-'0'))<8) { + /* overflow check; for each digit we multiply by 8 and then add the + * digit; 0-7 needs 3 bits of storage, so we need to check if the + * uppermost 3 bits of l are empty. Do it by shifting to the right */ if (l>>(sizeof(l)*8-3)) break; l=(unsigned short)(l*8+c); ++tmp; diff --git a/scan/scan_asn1derlength.c b/scan/scan_asn1derlength.c index db1d65c..a0b02d7 100644 --- a/scan/scan_asn1derlength.c +++ b/scan/scan_asn1derlength.c @@ -1,5 +1,26 @@ #include "scan.h" +/* ASN.1 DER encoded length: + * if (value<=0x80): + * emit value; + * otherwise: + * emit 0x80+bytes_that_follow + * emit all the bytes in the number, number saved big endian + * examples: + * 5 -> 0x05 + * 0xc2 -> 0x81 0xc2 + * 0x123 -> 0x82 0x01 0x23 + * 0x12345 -> 0x83 0x01 0x23 0x45 + */ + +/* We provide two functions. + * One that only parses the length value (scan_asn1derlengthvalue), and + * one that also makes sure that as many bytes as specified by the + * length are in the input buffer (scan_asn1derlength). + * If you are trying to parse ASN.1, use scan_asn1derlength. + * If you just want to use the integer encoding format used by ASN.1 DER + * for lengths, use scan_asn1derlengthvalue. */ + size_t scan_asn1derlengthvalue(const char* src,size_t len,unsigned long long* value) { if (len==0 || len>=-(uintptr_t)src) return 0; unsigned int i,c=*src; diff --git a/scan/scan_asn1dertag.c b/scan/scan_asn1dertag.c index a003d14..769482d 100644 --- a/scan/scan_asn1dertag.c +++ b/scan/scan_asn1dertag.c @@ -1,12 +1,22 @@ #include "scan.h" +/* ASN.1 DER tag encoding parser. + * Write value as big endian series of bytes, each containing seven + * bits. In each byte except the last, set the highest bit. + * Examples: + * 0 -> 0x00 + * 5 -> 0x05 + * 0xc2 -> 0x81 0x42 */ + size_t scan_asn1dertag(const char* src,size_t len,unsigned long long* length) { size_t n; unsigned long long l=0; if (len==0 || (unsigned char)src[0]==0x80) return 0; // catch non-minimal encoding for (n=0; n>(sizeof(l)*8-7)) return 0; // catch integer overflow l=(l<<7) | (src[n]&0x7f); + /* if high bit not set, this is the last byte in the sequence */ if (!(src[n]&0x80)) { *length=l; return n+1; diff --git a/scan/scan_charsetnskip.c b/scan/scan_charsetnskip.c index dd76a54..5d71aa5 100644 --- a/scan/scan_charsetnskip.c +++ b/scan/scan_charsetnskip.c @@ -1,6 +1,8 @@ #include "scan.h" #include +/* Return the number of leading chars in s that are in charset, but no + * more than limit */ size_t scan_charsetnskip(const char *s,const char *charset,size_t limit) { register const char *t=s; register const char *u=t+limit; diff --git a/socket.h b/socket.h index a0b9309..279545a 100644 --- a/socket.h +++ b/socket.h @@ -82,6 +82,7 @@ extern int noipv6; #include #include +#ifndef EWOULDBLOCK #define EWOULDBLOCK WSAEWOULDBLOCK #define EINPROGRESS WSAEINPROGRESS #define EALREADY WSAEALREADY @@ -118,6 +119,7 @@ extern int noipv6; #define ESTALE WSAESTALE #define EREMOTE WSAEREMOTE #define EDISCON WSAEDISCON +#endif #endif