ref: 8c27b1260d418feff94b033db3f721c8d7ee4e01
parent: 991f5e738ea8d43c3d7c5d0a6f43e1d3edcf2970
author: Tor Andersson <tor.andersson@artifex.com>
date: Thu Sep 7 10:22:43 EDT 2017
Fix leak in Function.prototype.toString.
--- a/jsfunction.c
+++ b/jsfunction.c
@@ -49,8 +49,8 @@
static void Fp_toString(js_State *J)
{
js_Object *self = js_toobject(J, 0);
- char *s;
- int i, n;
+ js_Buffer *sb = NULL;
+ int i;
if (!js_iscallable(J, 0))
js_typeerror(J, "not a function");
@@ -57,26 +57,37 @@
if (self->type == JS_CFUNCTION || self->type == JS_CSCRIPT) {
js_Function *F = self->u.f.function;
- n = strlen("function () { ... }");
- n += strlen(F->name);
- for (i = 0; i < F->numparams; ++i)
- n += strlen(F->vartab[i]) + 1;
- s = js_malloc(J, n + 1);
- strcpy(s, "function ");
- strcat(s, F->name);
- strcat(s, "(");
+
+ if (js_try(J)) {
+ js_free(J, sb);
+ js_throw(J);
+ }
+
+ js_puts(J, &sb, "function ");
+ js_puts(J, &sb, F->name);
+ js_putc(J, &sb, '(');
for (i = 0; i < F->numparams; ++i) {
- if (i > 0) strcat(s, ",");
- strcat(s, F->vartab[i]);
+ if (i > 0) js_putc(J, &sb, ',');
+ js_puts(J, &sb, F->vartab[i]);
}
- strcat(s, ") { ... }");
+ js_puts(J, &sb, ") { ... }");
+
+ js_pushstring(J, sb->s);
+ js_endtry(J);
+ js_free(J, sb);
+ } else if (self->type == JS_CCFUNCTION) {
if (js_try(J)) {
- js_free(J, s);
+ js_free(J, sb);
js_throw(J);
}
- js_pushstring(J, s);
- js_free(J, s);
+
+ js_puts(J, &sb, "function ");
+ js_puts(J, &sb, self->u.c.name);
+ js_puts(J, &sb, "() { ... }");
+
+ js_pushstring(J, sb->s);
js_endtry(J);
+ js_free(J, sb);
} else {
js_pushliteral(J, "function () { ... }");
}