SECURITY: check for integer overflow in stralloc_ready

master
leitner 11 years ago
parent 539ef564ab
commit f7fee036c1

@ -10,6 +10,7 @@
added fmt_escapechar* to fmt.h (implement various escaping mechanisms also found in textcode but for a single char not a whole string, and they always escape, not just when they think it's needed) added fmt_escapechar* to fmt.h (implement various escaping mechanisms also found in textcode but for a single char not a whole string, and they always escape, not just when they think it's needed)
scan_ushort was supposed to abort early and return 5 when attempting to parse "65536", because the result does not fit. It did not. Now it does. scan_ushort was supposed to abort early and return 5 when attempting to parse "65536", because the result does not fit. It did not. Now it does.
scan_*long, scan_*int, scan_*short now properly abort if the number would not fit scan_*long, scan_*int, scan_*short now properly abort if the number would not fit
SECURITY: check for integer overflow in stralloc_ready
0.29: 0.29:
save 8 bytes in taia.h for 64-bit systems save 8 bytes in taia.h for 64-bit systems

@ -4,4 +4,5 @@
void stralloc_free(stralloc *sa) { void stralloc_free(stralloc *sa) {
if (sa->s) free(sa->s); if (sa->s) free(sa->s);
sa->s=0; sa->s=0;
sa->a=sa->len=0;
} }

@ -9,7 +9,7 @@
* old space, and returns 1. Note that this changes sa.s. */ * old space, and returns 1. Note that this changes sa.s. */
int stralloc_ready(stralloc *sa,size_t len) { int stralloc_ready(stralloc *sa,size_t len) {
register size_t wanted=len+(len>>3)+30; /* heuristic from djb */ register size_t wanted=len+(len>>3)+30; /* heuristic from djb */
if (!sa->s || sa->a<len) { if (wanted<len || !sa->s || sa->a<len) {
register char* tmp; register char* tmp;
if (!(tmp=realloc(sa->s,wanted))) if (!(tmp=realloc(sa->s,wanted)))
return 0; return 0;

@ -1,14 +1,20 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <fmt.h> #include <fmt.h>
#include <scan.h> #include <scan.h>
#include <textcode.h> #include <textcode.h>
#include <byte.h> #include <byte.h>
#include <assert.h>
#include <uint16.h> #include <uint16.h>
#include <uint32.h> #include <uint32.h>
#include <uint64.h> #include <uint64.h>
#include <openreadclose.h>
#include <mmap.h>
char buf[100]; char buf[100];
stralloc sa;
void zap() { size_t i; for (i=0; i<sizeof(buf); ++i) buf[i]='_'; } void zap() { size_t i; for (i=0; i<sizeof(buf); ++i) buf[i]='_'; }
@ -26,6 +32,13 @@ int main() {
signed int i; signed int i;
signed short s; signed short s;
long flen;
char* stdiocopy;
#ifdef NDEBUG
#error This is a unit test that uses assert() or all checks, compile without -DNDEBUG!
#endif
// check utf8 encoding // check utf8 encoding
zap(); assert(fmt_utf8(NULL,12345) == 3); zap(); assert(fmt_utf8(NULL,12345) == 3);
zap(); assert(fmt_utf8(buf,12345) == 3 && byte_equal(buf,4,"\xe3\x80\xb9_")); zap(); assert(fmt_utf8(buf,12345) == 3 && byte_equal(buf,4,"\xe3\x80\xb9_"));
@ -306,5 +319,41 @@ int main() {
} }
} }
{
char* mmapcopy;
FILE* f;
size_t mlen;
assert(f=fopen("test/marshal.c","rb"));
assert(fseek(f,0,SEEK_END)==0);
flen=ftell(f);
assert(flen>4096);
fseek(f,0,SEEK_SET);
assert(stdiocopy=malloc(flen));
assert(fread(stdiocopy,1,flen,f)==flen);
fclose(f);
assert(openreadclose("test/marshal.c",&sa,4096)==1);
assert(sa.len == flen);
assert(byte_equal(sa.s,flen,stdiocopy));
assert((mmapcopy=mmap_read("test/marshal.c",&mlen)) && mlen==flen);
assert(byte_equal(sa.s,flen,mmapcopy));
mmap_unmap(mmapcopy,mlen);
}
stralloc_free(&sa);
assert(stralloc_ready(&sa,0x1000));
assert(sa.a >= 0x1000);
assert(stralloc_copyb(&sa,stdiocopy,0x900));
assert(sa.len == 0x900);
assert(stralloc_catb(&sa,stdiocopy+0x900,0x700));
assert(sa.len == 0x1000);
assert(byte_equal(sa.s,0x1000,stdiocopy));
assert(stralloc_readyplus(&sa,0x1000));
assert(sa.a >= 0x2000);
assert(stralloc_readyplus(&sa,(size_t)-1)==0);
assert(stralloc_ready(&sa,(size_t)-1)==0);
return 0; return 0;
} }

Loading…
Cancel
Save