Commit bd1875e1 authored by Geoff Simmons's avatar Geoff Simmons

bugfix resizing the format output buffer

parent b07b7515
Pipeline #5 skipped
......@@ -1454,20 +1454,21 @@ FMT_Estimate_RecsPerTx(void)
}
static inline void
fmt_resize(size_t curlen)
fmt_resize(size_t length)
{
if (curlen > obuf_sz) {
do { obuf_sz <<= 1; } while (curlen > obuf_sz);
/* Add 1 since we'll be appending a NUL byte */
if (length + 1 > obuf_sz) {
do { obuf_sz <<= 1; } while (length + 1 > obuf_sz);
obuf = realloc(obuf, obuf_sz);
AN(obuf);
}
}
char *
FMT_Format(tx_t *tx, size_t *curlen)
FMT_Format(tx_t *tx, size_t *length)
{
compiled_fmt_t fmt;
char *p = obuf;
size_t curlen = 0;
CHECK_OBJ_NOTNULL(tx, TX_MAGIC);
assert(tx->state == TX_SUBMITTED);
......@@ -1488,31 +1489,27 @@ FMT_Format(tx_t *tx, size_t *curlen)
tx->state = TX_FORMATTING;
/* Start curlen at 1, because we'll be appending a NUL byte */
*p = '\0';
*curlen = 1;
*obuf = '\0';
for (int i = 0; i < fmt.n; i++) {
char *s = NULL;
size_t len = 0;
if (fmt.str[i] != NULL) {
*curlen += fmt.strlen[i];
fmt_resize(*curlen);
memcpy(p, fmt.str[i], fmt.strlen[i]);
p += fmt.strlen[i];
fmt_resize(curlen + fmt.strlen[i]);
memcpy(obuf + curlen, fmt.str[i], fmt.strlen[i]);
curlen += fmt.strlen[i];
}
if (fmt.formatter[i] != NULL) {
(fmt.formatter[i])(tx, &fmt.args[i], &s, &len);
if (s != NULL && len != 0) {
*curlen += len;
fmt_resize(*curlen);
memcpy(p, s, len);
p += len;
fmt_resize(curlen + len);
memcpy(obuf + curlen, s, len);
curlen += len;
}
}
}
*p = '\0';
*curlen -= 1;
obuf[curlen] = '\0';
*length = curlen;
assert(tx->state == TX_FORMATTING);
tx->state = TX_WRITTEN;
......
......@@ -2333,6 +2333,45 @@ static const char
return NULL;
}
static const char
*test_long_output(void)
{
#define NFORMATS 8193
#define XID 47114711
#define xstr(s) #s
#define str(s) xstr(s)
char err[1024], *os;
int status;
tx_t tx;
size_t len;
struct vsb *exp;
printf("... testing long formatted output\n");
exp = VSB_new_auto();
VSB_clear(config.cformat);
for (int i = 0; i < NFORMATS; i++) {
VSB_cat(config.cformat, "%{vxid}x");
VSB_cat(exp, str(XID));
}
VSB_putc(exp, '\n');
VSB_finish(config.cformat);
VSB_finish(exp);
status = FMT_Init(err);
VMASSERT(status == 0, "FMT_Init: %s", err);
tx.magic = TX_MAGIC;
tx.state = TX_SUBMITTED;
tx.type = VSL_t_req;
tx.vxid = 47114711;
os = FMT_Format(&tx, &len);
MASSERT(len == NFORMATS * (sizeof(str(XID)) - 1) + 1);
MASSERT(strncmp(os, VSB_data(exp), len) == 0);
return NULL;
}
static const char
*all_tests(void)
{
......@@ -2366,6 +2405,7 @@ static const char
mu_run_test(test_format_p_vxid);
mu_run_test(test_FMT_Fini);
mu_run_test(test_FMT_interface);
mu_run_test(test_long_output);
return NULL;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment