]> granicus.if.org Git - graphviz/commitdiff
scformat: use vmalloc instead of vmresize when processing '['
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Mon, 19 Jul 2021 00:09:59 +0000 (17:09 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Wed, 28 Jul 2021 15:02:00 +0000 (08:02 -0700)
Though it is hard to see, the previous code bottomed out in a call to vmresize.
After allocating, it zeroes the allocated region. So vmresize (itself calling
realloc) signals an unnecessary constraint to the allocator that previous data
in this memory must be preserved.

To simplify this, this change converts the sequence to a vmfree of the prior
memory and then a new vmalloc, more clearly divorcing the new buffer from the
old one.

lib/expr/exeval.c

index eda92e258d3bd081c27827aff1eb4f4d6f933a39..0fa6e54f4e543d64da62b94d9b0b51a17ad3edc7 100644 (file)
@@ -463,7 +463,7 @@ scformat(Sfio_t* sp, void* vp, Sffmt_t* dp)
                *(void**)vp = &node->data.variable.symbol->value->data.constant.value;
                break;
        case 's':
-       case '[':
+       case '[': {
                if (node->type != STRING)
                {
                        exerror("scanf: %s: string variable address argument expected", node->data.variable.symbol->name);
@@ -472,9 +472,14 @@ scformat(Sfio_t* sp, void* vp, Sffmt_t* dp)
                if (node->data.variable.symbol->value->data.constant.value.string == expr.nullstring)
                        node->data.variable.symbol->value->data.constant.value.string = 0;
                fmt->fmt.size = 1024;
-               *(void**)vp = node->data.variable.symbol->value->data.constant.value.string = vmnewof(fmt->expr->vm, node->data.variable.symbol->value->data.constant.value.string, char, fmt->fmt.size, 0);
-               memset(node->data.variable.symbol->value->data.constant.value.string, 0, sizeof(char) * (size_t)fmt->fmt.size);
+               char *s = node->data.variable.symbol->value->data.constant.value.string;
+               vmfree(fmt->expr->vm, s);
+               s = vmalloc(fmt->expr->vm, sizeof(char) * (size_t)fmt->fmt.size);
+               memset(s, 0, sizeof(char) * (size_t)fmt->fmt.size);
+               *(void**)vp = s;
+               node->data.variable.symbol->value->data.constant.value.string = s;
                break;
+       }
        case 'c':
                if (node->type != CHARACTER) {
                        exerror("scanf: %s: char variable address argument expected", node->data.variable.symbol->name);