diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index 58f830dd..f33146e3 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -559,7 +559,8 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp element = &signature->elements[signature->element_count++]; memset(element, 0, sizeof(*element)); - element->semantic_name = name; + if (!(element->semantic_name = vkd3d_strdup(name))) + return false; element->semantic_index = index; element->sysval_semantic = sysval; element->component_type = VKD3D_SHADER_COMPONENT_FLOAT; diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 8a1012d9..4b9f6723 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -360,7 +360,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s uint32_t count, header_size; struct signature_element *e; const char *ptr = data; - unsigned int i; + unsigned int i, j; if (!require_space(0, 2, sizeof(uint32_t), section->data.size)) { @@ -403,6 +403,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s for (i = 0; i < count; ++i) { size_t name_offset; + const char *name; uint32_t mask; e[i].sort_index = i; @@ -413,9 +414,14 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s e[i].stream_index = 0; name_offset = read_u32(&ptr); - if (!(e[i].semantic_name = shader_get_string(data, section->data.size, name_offset))) + if (!(name = shader_get_string(data, section->data.size, name_offset)) + || !(e[i].semantic_name = vkd3d_strdup(name))) { WARN("Invalid name offset %#zx (data size %#zx).\n", name_offset, section->data.size); + for (j = 0; j < i; ++j) + { + vkd3d_free((void *)e[j].semantic_name); + } vkd3d_free(e); return VKD3D_ERROR_INVALID_ARGUMENT; } diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 4943a586..73a8d868 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -9445,7 +9445,22 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const } } - vkd3d_free(s->elements); + for (i = 0; i < operand_count; ++i) + { + if ((elements[i].semantic_name = vkd3d_strdup(elements[i].semantic_name))) + continue; + + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Failed to allocate signature element semantic name."); + for (j = 0; j < i; ++j) + { + vkd3d_free((void *)elements[j].semantic_name); + } + vkd3d_free(elements); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + + shader_signature_cleanup(s); s->elements = elements; s->element_count = operand_count; diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 27a88a12..cee7a296 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -657,7 +657,15 @@ static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_sig struct vkd3d_shader_signature_element *d = &signature->elements[i]; struct signature_element *e = &src->elements[i]; - d->semantic_name = e->semantic_name; + if (!(d->semantic_name = vkd3d_strdup(e->semantic_name))) + { + for (unsigned int j = 0; j < i; ++j) + { + vkd3d_free((void *)signature->elements[j].semantic_name); + } + vkd3d_free(signature->elements); + return false; + } d->semantic_index = e->semantic_index; d->stream_index = e->stream_index; d->sysval_semantic = e->sysval_semantic; @@ -1763,6 +1771,10 @@ void vkd3d_shader_free_root_signature(struct vkd3d_shader_versioned_root_signatu void shader_signature_cleanup(struct shader_signature *signature) { + for (unsigned int i = 0; i < signature->element_count; ++i) + { + vkd3d_free((void *)signature->elements[i].semantic_name); + } vkd3d_free(signature->elements); signature->elements = NULL; } @@ -1820,6 +1832,10 @@ void vkd3d_shader_free_shader_signature(struct vkd3d_shader_signature *signature { TRACE("signature %p.\n", signature); + for (unsigned int i = 0; i < signature->element_count; ++i) + { + vkd3d_free((void *)signature->elements[i].semantic_name); + } vkd3d_free(signature->elements); signature->elements = NULL; }