diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-13 13:39:50 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-13 13:56:37 +0300 |
commit | 58f7dbc0658b3d73816a1bc91b75c2bdac733510 (patch) | |
tree | 3d971a9b1a3fd25ca46588112c3a314f971d584f /src | |
parent | 23f262e8c6181465347c3bb47644f9d86fcb7432 (diff) | |
download | vmod-binlog-58f7dbc0658b3d73816a1bc91b75c2bdac733510.tar.gz vmod-binlog-58f7dbc0658b3d73816a1bc91b75c2bdac733510.tar.bz2 |
Fix error checking, add pack tests.
* src/binlog.c (vmod_init): Fix error checking after packcomp.
* src/binlogcat.c (catlog): Likewise.
* tests/binpack.c (main): Likewise.
* src/pack.c (Z_unpacker): Fix output format.
(packcomp): allow for whitespace between specifiers. On error
set errno and return NULL.
* tests/Makefile.am: Add pack.at
* tests/testsuite.at: Likewise.
* tests/pack.at: New file.
* tests/test02.at: Fix name pattern.
Diffstat (limited to 'src')
-rw-r--r-- | src/binlog.c | 8 | ||||
-rw-r--r-- | src/binlogcat.c | 11 | ||||
-rw-r--r-- | src/pack.c | 30 |
3 files changed, 36 insertions, 13 deletions
diff --git a/src/binlog.c b/src/binlog.c index 7e88817..765b945 100644 --- a/src/binlog.c +++ b/src/binlog.c @@ -220,9 +220,11 @@ vmod_init(struct sess *sp, struct vmod_priv *priv, AN(conf->dir); conf->inst_head = packcomp(dataspec, &p); - AN(conf->inst_head); - if (*p) { - binlog_error("cannot compile data format near %s", p); + if (!conf->inst_head) { + if (errno == EINVAL) + binlog_error("cannot compile data format near %s", p); + else + binlog_error("%s", strerror(errno)); abort(); } conf->recsize = packsize(conf->inst_head); diff --git a/src/binlogcat.c b/src/binlogcat.c index bdeb992..505bbc2 100644 --- a/src/binlogcat.c +++ b/src/binlogcat.c @@ -92,8 +92,13 @@ catlog(const char *fname) fname, dataspec, header.recsize, header.recnum); inst = packcomp(dataspec, &p); - if (*p) { - error("%s: bad dataspec near %s", dataspec, p); + if (!inst) { + if (errno == EINVAL) { + error("%s: bad dataspec near %s", dataspec, p); + exit(1); + } + + error("%s", strerror(errno)); exit(1); } free(dataspec); @@ -101,7 +106,7 @@ catlog(const char *fname) rec = malloc(header.recsize); if (!rec) { error("not enough memory"); - abort(); + exit(1); } env = packenv_create(header.recsize - offsetof(struct binlog_record,data)); @@ -35,7 +35,6 @@ null padded. This letter must be followed by repeat count. c A signed char (8-bit) value. - C An unsigned char (octet) value. s A signed short (16-bit) value. S An unsigned short value. @@ -221,7 +220,7 @@ Z_packer(struct packenv *env, int rep) static void Z_unpacker(struct packenv *env, int rep) { - fprintf(env->fp, "%-*.*s", rep, rep, env->buf_base + env->buf_pos); + fprintf(env->fp, "%-*.*s", rep-1, rep-1, env->buf_base + env->buf_pos); env->buf_pos += rep; } @@ -672,18 +671,30 @@ packcomp(const char *s, char **endp) struct packinst *head = NULL, *tail = NULL, *pi; struct packspec *ps; int rep; + int ec = 0; - while (s) { + errno = 0; + while (*s) { + if (isspace(*s)) { + ++s; + continue; + } for (ps = packspec; ps->ch; ps++) if (ps->ch == *s) break; - if (!ps->ch) + if (!ps->ch) { + ec = EINVAL; break; - if (getrep(s + 1, &s, &rep)) + } + if (getrep(s + 1, &s, &rep)) { + ec = EINVAL; break; + } pi = malloc(sizeof(*pi)); - if (!pi) - return NULL; + if (!pi) { + ec = ENOMEM; + break; + } pi->next = NULL; pi->spec = ps; pi->rep = rep; @@ -693,6 +704,11 @@ packcomp(const char *s, char **endp) head = pi; tail = pi; } + if (ec) { + packfree(head); + head = NULL; + errno = ec; + } if (endp) *endp = (char*) s; return head; |