]> granicus.if.org Git - graphviz/commitdiff
use a local buffer for expr sprintf instead of a persistent one
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 10 Apr 2021 20:12:34 +0000 (13:12 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sun, 18 Apr 2021 01:11:21 +0000 (18:11 -0700)
Though this introduces another call to sfstropen, it is actually a step towards
removing sfstropen calls. The first part of this is localizing existing usages;
avoiding the ex->tmp buffer. Then the implementation of expr’s sprintf itself
will need to be refactored to operate on a non-SFIO buffer.

Note that this also addresses an issue where expr’s sprintf would use the
persistent buffer even if prior opening of it had failed due to lack of memory.

Related to #1873.

lib/expr/exeval.c

index 9c12a210af89c3efca647e08e9fcff0ed2412149..786b562e38a996730a9a9a2196acef6f08d62768 100644 (file)
@@ -1283,10 +1283,17 @@ eval(Expr_t* ex, Exnode_t* expr, void* env)
        case SSCANF:
                v.integer = scan(ex, expr, env, NULL);
                return v;
-       case SPRINTF:
-               print(ex, expr, env, ex->tmp);
-               v.string = exstash(ex->tmp, ex->ve);
+       case SPRINTF: {
+               Sfio_t *buffer = sfstropen();
+               if (buffer == NULL) {
+                       fprintf(stderr, "out of memory\n");
+                       exit(EXIT_FAILURE);
+               }
+               print(ex, expr, env, buffer);
+               v.string = exstash(buffer, ex->ve);
+               sfstrclose(buffer);
                return v;
+       }
        case '=':
                v = eval(ex, expr->data.operand.right, env);
                if (expr->subop != '=')