From: Robert Spalek Date: Mon, 28 Jun 2004 09:34:27 +0000 (+0000) Subject: - encapsulation: hide struct lizard_buffer in the source code X-Git-Tag: holmes-import~996 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=54952ff4cd9e28755d0fb0d38e2dab3c1299a6ab;p=libucw.git - encapsulation: hide struct lizard_buffer in the source code ===> interface changed, now it returns the pointer in one extra parameter - lizard_alloc() allocates no memory, hence no size parameter needed - lizard_realloc() made static and it is automatically called by the decompression routine --- diff --git a/lib/lizard-safe.c b/lib/lizard-safe.c index 218faec2..dcc01d11 100644 --- a/lib/lizard-safe.c +++ b/lib/lizard-safe.c @@ -18,28 +18,18 @@ #include #include -static void -lizard_alloc_internal(struct lizard_buffer *buf, uns max_len) -{ - if (!max_len) - { - buf->len = 0; - buf->start = NULL; - return; - } - buf->len = ALIGN(max_len + 3, PAGE_SIZE); // +3 due to the unaligned access - buf->start = mmap(NULL, buf->len + PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if (buf->start == MAP_FAILED) - die("mmap(anonymous): %m"); - if (mprotect(buf->start + buf->len, PAGE_SIZE, PROT_NONE) < 0) - die("mprotect: %m"); -} +struct lizard_buffer { + uns len; + void *ptr; + struct sigaction *old_sigsegv_handler; +}; struct lizard_buffer * -lizard_alloc(uns max_len) +lizard_alloc(void) { struct lizard_buffer *buf = xmalloc(sizeof(struct lizard_buffer)); - lizard_alloc_internal(buf, max_len); + buf->len = 0; + buf->ptr = NULL; buf->old_sigsegv_handler = xmalloc(sizeof(struct sigaction)); handle_signal(SIGSEGV, buf->old_sigsegv_handler); return buf; @@ -48,24 +38,30 @@ lizard_alloc(uns max_len) void lizard_free(struct lizard_buffer *buf) { - if (buf->start) - munmap(buf->start, buf->len + PAGE_SIZE); + if (buf->ptr) + munmap(buf->ptr, buf->len + PAGE_SIZE); unhandle_signal(SIGSEGV, buf->old_sigsegv_handler); xfree(buf->old_sigsegv_handler); xfree(buf); } -void +static void lizard_realloc(struct lizard_buffer *buf, uns max_len) + /* max_len needs to be aligned to PAGE_SIZE */ { - max_len += 3; if (max_len <= buf->len) return; - if (max_len < 2*buf->len) // to ensure amortized logarithmic complexity + if (max_len < 2*buf->len) // to ensure logarithmic cost max_len = 2*buf->len; - if (buf->start) - munmap(buf->start - 3, buf->len + PAGE_SIZE); - lizard_alloc_internal(buf, max_len); + + if (buf->ptr) + munmap(buf->ptr, buf->len + PAGE_SIZE); + buf->len = max_len; + buf->ptr = mmap(NULL, buf->len + PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (buf->ptr == MAP_FAILED) + die("mmap(anonymous): %m"); + if (mprotect(buf->ptr + buf->len, PAGE_SIZE, PROT_NONE) < 0) + die("mprotect: %m"); } static jmp_buf safe_decompress_jump; @@ -78,29 +74,27 @@ sigsegv_handler(int signal UNUSED) } int -lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length) - /* Decompresses into buf->ptr and returns the length of the uncompressed - * file. If an error has occured, -1 is returned and errno is set. SIGSEGV - * is caught in the case of buffer-overflow. The function is not re-entrant - * because of a static longjmp handler. */ +lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length, byte **ptr) + /* Decompresses in into buf, sets *ptr to the data, and returns the + * uncompressed length. If an error has occured, -1 is returned and errno is + * set. The buffer buf is automatically reallocated. SIGSEGV is caught in + * case of buffer-overflow. The function is not re-entrant because of a + * static longjmp handler. */ { uns lock_offset = ALIGN(expected_length + 3, PAGE_SIZE); // +3 due to the unaligned access if (lock_offset > buf->len) - { - errno = EFBIG; - return -1; - } + lizard_realloc(buf, lock_offset); volatile sh_sighandler_t old_handler = signal_handler[SIGSEGV]; signal_handler[SIGSEGV] = sigsegv_handler; int len; if (!setjmp(safe_decompress_jump)) { - buf->ptr = buf->start + buf->len - lock_offset; - len = lizard_decompress(in, buf->ptr); + *ptr = buf->ptr + buf->len - lock_offset; + len = lizard_decompress(in, *ptr); } else { - buf->ptr = NULL; + *ptr = NULL; len = -1; errno = EFAULT; } diff --git a/lib/lizard.h b/lib/lizard.h index 3f72b96c..bbd2a838 100644 --- a/lib/lizard.h +++ b/lib/lizard.h @@ -20,7 +20,7 @@ * The multiplicative constant comes from 19-byte incompressible string * followed by a 3-sequence that can be compressed into 2-byte link. This * breaks the copy-mode and it needs to be restarted with a new header. The - * total length is 2(header) + 2(link) + 19(string) = 23. + * total length is 2(header) + 19(string) + 2(link) = 23. */ /* lizard.c */ @@ -28,14 +28,8 @@ int lizard_compress(byte *in, uns in_len, byte *out); int lizard_decompress(byte *in, byte *out); /* lizard-safe.c */ -struct sigaction; -struct lizard_buffer { - uns len; - void *start, *ptr; - struct sigaction *old_sigsegv_handler; -}; +struct lizard_buffer; -struct lizard_buffer *lizard_alloc(uns max_len); +struct lizard_buffer *lizard_alloc(void); void lizard_free(struct lizard_buffer *buf); -void lizard_realloc(struct lizard_buffer *buf, uns max_len); -int lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length); +int lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length, byte **ptr);