From f7e09276227e23a17626b292279326e51b2b2708 Mon Sep 17 00:00:00 2001 From: Matteo Bruni Date: Wed, 29 Apr 2015 23:34:28 +0200 Subject: [PATCH] wined3d: Don't use the same va_list multiple times in shader_vaddline(). --- dlls/wined3d/glsl_shader.c | 14 ++++++-- dlls/wined3d/shader.c | 79 ++++++++++++++++++++++++------------------ dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 58 insertions(+), 36 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index e814c66acbd..19c3d317294 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -2762,6 +2762,7 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s struct color_fixup_desc fixup; BOOL np2_fixup = FALSE; va_list args; + int ret; shader_glsl_swizzle_to_str(swizzle, FALSE, ins->dst[0].write_mask, dst_swizzle); @@ -2791,9 +2792,16 @@ static void PRINTF_ATTR(8, 9) shader_glsl_gen_sample_code(const struct wined3d_s shader_addline(ins->ctx->buffer, "%s(%s_sampler%u, ", sample_function->name, shader_glsl_get_prefix(version->type), sampler); - va_start(args, coord_reg_fmt); - shader_vaddline(ins->ctx->buffer, coord_reg_fmt, args); - va_end(args); + for (;;) + { + va_start(args, coord_reg_fmt); + ret = shader_vaddline(ins->ctx->buffer, coord_reg_fmt, args); + va_end(args); + if (!ret) + break; + if (!string_buffer_resize(ins->ctx->buffer, ret)) + break; + } if(bias) { shader_addline(ins->ctx->buffer, ", %s)%s);\n", bias, dst_swizzle); diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index 87a22c2bbea..279ec423f68 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -269,35 +269,35 @@ void string_buffer_free(struct wined3d_string_buffer *buffer) HeapFree(GetProcessHeap(), 0, buffer->buffer); } -int shader_vaddline(struct wined3d_string_buffer *buffer, const char *format, va_list args) +BOOL string_buffer_resize(struct wined3d_string_buffer *buffer, int rc) { - unsigned int rem; - int rc; char *new_buffer; - unsigned int new_buffer_size; + unsigned int new_buffer_size = buffer->buffer_size * 2; - for (;;) + while (rc > 0 && (unsigned int)rc >= new_buffer_size - buffer->content_size) + new_buffer_size *= 2; + if (!(new_buffer = HeapReAlloc(GetProcessHeap(), 0, buffer->buffer, new_buffer_size))) { - rem = buffer->buffer_size - buffer->content_size; - rc = vsnprintf(&buffer->buffer[buffer->content_size], rem, format, args); + ERR("Failed to grow buffer.\n"); + buffer->buffer[buffer->content_size] = '\0'; + return FALSE; + } + buffer->buffer = new_buffer; + buffer->buffer_size = new_buffer_size; + return TRUE; +} - if (rc >= 0 /* C89 */ && (unsigned int)rc < rem /* C99 */) - break; +int shader_vaddline(struct wined3d_string_buffer *buffer, const char *format, va_list args) +{ + unsigned int rem; + int rc; - new_buffer_size = buffer->buffer_size * 2; - while (rc > 0 && (unsigned int)rc >= new_buffer_size - buffer->content_size) - new_buffer_size *= 2; - if (!(new_buffer = HeapReAlloc(GetProcessHeap(), 0, buffer->buffer, new_buffer_size))) - { - ERR("Failed to grow buffer.\n"); - buffer->buffer[buffer->content_size] = '\0'; - return -1; - } - buffer->buffer = new_buffer; - buffer->buffer_size = new_buffer_size; - } - buffer->content_size += rc; + rem = buffer->buffer_size - buffer->content_size; + rc = vsnprintf(&buffer->buffer[buffer->content_size], rem, format, args); + if (rc < 0 /* C89 */ || (unsigned int)rc >= rem /* C99 */) + return rc; + buffer->content_size += rc; return 0; } @@ -306,11 +306,16 @@ int shader_addline(struct wined3d_string_buffer *buffer, const char *format, ... va_list args; int ret; - va_start(args, format); - ret = shader_vaddline(buffer, format, args); - va_end(args); - - return ret; + for (;;) + { + va_start(args, format); + ret = shader_vaddline(buffer, format, args); + va_end(args); + if (!ret) + return ret; + if (!string_buffer_resize(buffer, ret)) + return -1; + } } struct wined3d_string_buffer *string_buffer_get(struct wined3d_string_buffer_list *list) @@ -337,21 +342,29 @@ struct wined3d_string_buffer *string_buffer_get(struct wined3d_string_buffer_lis return buffer; } -static void string_buffer_vsprintf(struct wined3d_string_buffer *buffer, const char *format, va_list args) +static int string_buffer_vsprintf(struct wined3d_string_buffer *buffer, const char *format, va_list args) { if (!buffer) - return; + return 0; string_buffer_clear(buffer); - shader_vaddline(buffer, format, args); + return shader_vaddline(buffer, format, args); } void string_buffer_sprintf(struct wined3d_string_buffer *buffer, const char *format, ...) { va_list args; + int ret; - va_start(args, format); - string_buffer_vsprintf(buffer, format, args); - va_end(args); + for (;;) + { + va_start(args, format); + ret = string_buffer_vsprintf(buffer, format, args); + va_end(args); + if (!ret) + return; + if (!string_buffer_resize(buffer, ret)) + return; + } } void string_buffer_release(struct wined3d_string_buffer_list *list, struct wined3d_string_buffer *buffer) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 459c55a7997..fafdb20dab2 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2896,6 +2896,7 @@ void string_buffer_list_init(struct wined3d_string_buffer_list *list) DECLSPEC_H void string_buffer_list_cleanup(struct wined3d_string_buffer_list *list) DECLSPEC_HIDDEN; int shader_addline(struct wined3d_string_buffer *buffer, const char *fmt, ...) PRINTF_ATTR(2,3) DECLSPEC_HIDDEN; +BOOL string_buffer_resize(struct wined3d_string_buffer *buffer, int rc) DECLSPEC_HIDDEN; int shader_vaddline(struct wined3d_string_buffer *buffer, const char *fmt, va_list args) DECLSPEC_HIDDEN; /* Vertex shader utility functions */ -- 2.11.4.GIT