Commit 5b67c574 authored by Geoff Simmons's avatar Geoff Simmons

fix a bug that caused formatters to overwrite header payloads if

there is more than one in a record spanning more than one chunk
parent 142a1c14
......@@ -53,7 +53,7 @@ typedef struct compiled_fmt_t {
} compiled_fmt_t;
static struct vsb payload_storage, * const payload = &payload_storage,
*i_arg, *scratch;
*i_arg, *scratch, hdr_storage, * const hdr_sb = &hdr_storage;
static char empty[] = "";
static char hit[] = "hit";
......@@ -137,25 +137,33 @@ get_hdr(const tx_t *tx, enum VSL_tag_e tag, const char *hdr)
CHECK_OBJ_NOTNULL(tx, TX_MAGIC);
VSTAILQ_FOREACH(rec, &tx->recs, reclist) {
char *c;
char *c, *h;
CHECK_OBJ_NOTNULL(rec, RECORD_MAGIC);
assert(OCCUPIED(rec));
if (rec->tag != tag)
continue;
c = get_payload(rec);
while (isspace(*c))
c++;
if (strncasecmp(c, hdr, strlen(hdr)) != 0)
h = c;
while (isspace(*h))
h++;
if (strncasecmp(h, hdr, strlen(hdr)) != 0)
continue;
c += strlen(hdr);
while (isspace(*c))
c++;
if (*c++ != ':')
h += strlen(hdr);
while (isspace(*h))
h++;
if (*h++ != ':')
continue;
while (isspace(*c))
c++;
hdr_payload = c;
while (isspace(*h))
h++;
if (rec->len <= config.chunk_size)
hdr_payload = h;
else {
VSB_clear(hdr_sb);
VSB_bcpy(hdr_sb, h, rec->len - (h - c));
VSB_finish(hdr_sb);
hdr_payload = VSB_data(hdr_sb);
}
}
return hdr_payload;
}
......@@ -1212,6 +1220,7 @@ int
FMT_Init(char *err)
{
AN(VSB_new(payload, NULL, config.max_reclen + 1, VSB_FIXEDLEN));
AN(VSB_new(hdr_sb, NULL, config.max_reclen + 1, VSB_FIXEDLEN));
i_arg = VSB_new_auto();
AN(i_arg);
scratch = VSB_new_auto();
......
......@@ -210,8 +210,8 @@ static const char
{
tx_t tx;
rec_t recs[NRECORDS];
chunk_t c[NRECORDS];
char *hdr;
chunk_t c[NRECORDS], *c1, *c2;
char *hdr, *exp;
printf("... testing get_hdr()\n");
......@@ -252,6 +252,45 @@ static const char
MAN(hdr);
MASSERT(strcmp(hdr, "wilco") == 0);
/* Different headers after the matching header */
hdr = get_hdr(&tx, SLT_ReqHeader, "Bar");
MAN(hdr);
MASSERT(strcmp(hdr, "baz") == 0);
/* Different headers spanning more than one chunk after the matching
* header */
c1 = (chunk_t *) calloc(1, sizeof(chunk_t));
MAN(c1);
c1->magic = CHUNK_MAGIC;
c1->data = (char *) calloc(1, config.chunk_size);
MAN(c1->data);
c1->occupied = 1;
VSTAILQ_INSERT_TAIL(&recs[NRECORDS - 2].chunks, c1, chunklist);
recs[NRECORDS - 2].len = config.chunk_size * 2;
strcpy(c[NRECORDS - 2].data, "Garply: ");
memset(c[NRECORDS - 2].data + strlen("Garply : ") - 1, 'x',
config.chunk_size - strlen("Garply: "));
memset(c1->data, 'x', config.chunk_size);
c2 = (chunk_t *) calloc(1, sizeof(chunk_t));
MAN(c2);
c2->magic = CHUNK_MAGIC;
c2->data = (char *) calloc(1, config.chunk_size);
MAN(c2->data);
c2->occupied = 1;
VSTAILQ_INSERT_TAIL(&recs[NRECORDS - 1].chunks, c2, chunklist);
recs[NRECORDS - 1].len = config.chunk_size * 2;
strcpy(c[NRECORDS - 1].data, "Xyzzy: ");
memset(c[NRECORDS - 1].data + strlen("Xyzzy : ") - 1, 'y',
config.chunk_size - strlen("Xyzzy: "));
memset(c2->data, 'y', config.chunk_size);
hdr = get_hdr(&tx, SLT_ReqHeader, "Garply");
MAN(hdr);
int len = 2 * config.chunk_size - strlen("Garply: ");
exp = (char *) malloc(len);
MAN(exp);
memset(exp, 'x', len);
MASSERT(memcmp(hdr, exp, len) == 0);
/* Record not found */
recs[NRECORDS / 2].tag = SLT_RespHeader;
recs[NRECORDS - 1].tag = SLT_RespHeader;
......
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