X-Git-Url: https://git.dlugolecki.net.pl/?a=blobdiff_plain;f=gedcom%2Fbuffer.c;h=0c3e17ca8cc094ad4925f47924266faafe23bbca;hb=0ed444394c30a2e3983fb551e7f788804116a8b4;hp=c09eaa548db7b7b179493a79f8e981e5a159a591;hpb=f908d7f1b11f6852672662bfe63e7e09f7a2b8ad;p=gedcom-parse.git diff --git a/gedcom/buffer.c b/gedcom/buffer.c index c09eaa5..0c3e17c 100644 --- a/gedcom/buffer.c +++ b/gedcom/buffer.c @@ -33,8 +33,11 @@ void reset_buffer(struct safe_buffer* b) { - if (b && b->buffer != NULL) - b->buffer[0] = '\0'; + if (b && b->buffer != NULL) { + memset(b->buffer, 0, b->bufsize); + b->buf_end = b->buffer; + b->buflen = 0; + } } void cleanup_buffer(struct safe_buffer *b) @@ -48,8 +51,10 @@ void init_buffer(struct safe_buffer *b) if (b && b->buffer == NULL) { b->buffer = (char *)malloc(INITIAL_BUF_SIZE); if (b->buffer) { - b->buffer[0] = '\0'; b->bufsize = INITIAL_BUF_SIZE; + memset(b->buffer, 0, b->bufsize); + b->buf_end = b->buffer; + b->buflen = 0; if (b->cleanup_func && atexit(b->cleanup_func) != 0) { fprintf(stderr, _("Could not register buffer cleanup function")); fprintf(stderr, "\n"); @@ -63,31 +68,46 @@ void init_buffer(struct safe_buffer *b) } } +void grow_buffer(struct safe_buffer *b) +{ + char* new_buffer; + size_t old_size = b->bufsize; + b->bufsize *= 2; + new_buffer = realloc(b->buffer, b->bufsize); + if (new_buffer) { + b->buffer = new_buffer; + memset(b->buffer + old_size, 0, b->bufsize - old_size); + b->buf_end = b->buffer + b->buflen; + } + else + b->buffer = NULL; +} + int safe_buf_vappend(struct safe_buffer *b, const char *s, va_list ap) { int res = 0; - int len; init_buffer(b); if (b && b->buffer) { - len = strlen(b->buffer); while (1) { - char *buf_ptr = b->buffer + len; - int rest_size = b->bufsize - len; + int rest_size = b->bufsize - b->buflen; #if HAVE_VSNPRINTF - res = vsnprintf(buf_ptr, rest_size, s, ap); + res = vsnprintf(b->buf_end, rest_size, s, ap); if (res > -1 && res < rest_size) { + b->buf_end = b->buf_end + res; + b->buflen = b->buflen + res; break; } - else { - b->bufsize *= 2; - b->buffer = realloc(b->buffer, b->bufsize); + else { + grow_buffer(b); } #else /* not HAVE_VSNPRINTF */ # if HAVE_VSPRINTF # warning "Using VSPRINTF. Buffer overflow could happen!" - vsprintf(buf_ptr, s, ap); + res = vsprintf(b->buf_end, s, ap); + b->buf_end = b->buf_end + res; + b->buflen = b->buflen + res; break; # else /* not HAVE_VPRINTF */ # error "Your standard library has neither vsnprintf nor vsprintf defined. One of them is required!"