--- a/ucx/buffer.c Tue Feb 16 17:39:33 2016 +0100 +++ b/ucx/buffer.c Mon May 23 12:28:32 2016 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2015 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,22 +31,22 @@ #include <stdlib.h> #include <string.h> -UcxBuffer *ucx_buffer_new(void *space, size_t size, int flags) { +UcxBuffer *ucx_buffer_new(void *space, size_t capacity, int flags) { UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer)); if (buffer) { buffer->flags = flags; if (!space) { - buffer->space = (char*)malloc(size); + buffer->space = (char*)malloc(capacity); if (!buffer->space) { free(buffer); return NULL; } - memset(buffer->space, 0, size); + memset(buffer->space, 0, capacity); buffer->flags |= UCX_BUFFER_AUTOFREE; } else { buffer->space = (char*)space; } - buffer->capacity = size; + buffer->capacity = capacity; buffer->size = 0; buffer->pos = 0; @@ -64,13 +64,8 @@ UcxBuffer* ucx_buffer_extract( UcxBuffer *src, size_t start, size_t length, int flags) { - if(src->size == 0) { - return NULL; - } - if (length == 0) { - length = src->size - start; - } - if (start+length > src->size) { + + if (src->size == 0 || length == 0 || start+length > src->capacity) { return NULL; } @@ -99,13 +94,21 @@ case SEEK_END: npos = buffer->size; break; + case SEEK_SET: + npos = 0; + break; default: - npos = 0; + return -1; } + size_t opos = npos; npos += offset; - if (npos > buffer->size) { + if ((offset > 0 && npos < opos) || (offset < 0 && npos > opos)) { + return -1; + } + + if (npos >= buffer->size) { return -1; } else { buffer->pos = npos; @@ -120,7 +123,17 @@ int ucx_buffer_extend(UcxBuffer *buffer, size_t len) { size_t newcap = buffer->capacity; - while (buffer->pos + len > newcap) newcap <<= 1; + + if (buffer->capacity + len < buffer->capacity) { + return -1; + } + + while (buffer->capacity + len > newcap) { + newcap <<= 1; + if (newcap < buffer->capacity) { + return -1; + } + } char *newspace = (char*)realloc(buffer->space, newcap); if (newspace) { @@ -137,18 +150,25 @@ size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems, UcxBuffer *buffer) { size_t len = size * nitems; - if (buffer->pos + len > buffer->capacity) { + size_t required = buffer->pos + len; + if (buffer->pos > required) { + return 0; + } + + if (required > buffer->capacity) { if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) { - if(ucx_buffer_extend(buffer, len)) { - return -1; + if (ucx_buffer_extend(buffer, required - buffer->capacity)) { + return 0; } } else { len = buffer->capacity - buffer->pos; - if (size > 1) len -= len%size; + if (size > 1) { + len -= len%size; + } } } - if (len <= 0) { + if (len == 0) { return len; }