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 | |
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.
-rw-r--r-- | src/binlog.c | 8 | ||||
-rw-r--r-- | src/binlogcat.c | 11 | ||||
-rw-r--r-- | src/pack.c | 30 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/binpack.c | 13 | ||||
-rw-r--r-- | tests/pack.at | 47 | ||||
-rw-r--r-- | tests/test02.at | 2 | ||||
-rw-r--r-- | tests/testsuite.at | 2 |
8 files changed, 95 insertions, 19 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, | |||
220 | AN(conf->dir); | 220 | AN(conf->dir); |
221 | 221 | ||
222 | conf->inst_head = packcomp(dataspec, &p); | 222 | conf->inst_head = packcomp(dataspec, &p); |
223 | AN(conf->inst_head); | 223 | if (!conf->inst_head) { |
224 | if (*p) { | 224 | if (errno == EINVAL) |
225 | binlog_error("cannot compile data format near %s", p); | 225 | binlog_error("cannot compile data format near %s", p); |
226 | else | ||
227 | binlog_error("%s", strerror(errno)); | ||
226 | abort(); | 228 | abort(); |
227 | } | 229 | } |
228 | conf->recsize = packsize(conf->inst_head); | 230 | 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) | |||
92 | fname, dataspec, header.recsize, header.recnum); | 92 | fname, dataspec, header.recsize, header.recnum); |
93 | 93 | ||
94 | inst = packcomp(dataspec, &p); | 94 | inst = packcomp(dataspec, &p); |
95 | if (*p) { | 95 | if (!inst) { |
96 | error("%s: bad dataspec near %s", dataspec, p); | 96 | if (errno == EINVAL) { |
97 | error("%s: bad dataspec near %s", dataspec, p); | ||
98 | exit(1); | ||
99 | } | ||
100 | |||
101 | error("%s", strerror(errno)); | ||
97 | exit(1); | 102 | exit(1); |
98 | } | 103 | } |
99 | free(dataspec); | 104 | free(dataspec); |
@@ -101,7 +106,7 @@ catlog(const char *fname) | |||
101 | rec = malloc(header.recsize); | 106 | rec = malloc(header.recsize); |
102 | if (!rec) { | 107 | if (!rec) { |
103 | error("not enough memory"); | 108 | error("not enough memory"); |
104 | abort(); | 109 | exit(1); |
105 | } | 110 | } |
106 | env = packenv_create(header.recsize - | 111 | env = packenv_create(header.recsize - |
107 | offsetof(struct binlog_record,data)); | 112 | offsetof(struct binlog_record,data)); |
@@ -35,7 +35,6 @@ | |||
35 | null padded. This letter must be followed by repeat count. | 35 | null padded. This letter must be followed by repeat count. |
36 | 36 | ||
37 | c A signed char (8-bit) value. | 37 | c A signed char (8-bit) value. |
38 | C An unsigned char (octet) value. | ||
39 | 38 | ||
40 | s A signed short (16-bit) value. | 39 | s A signed short (16-bit) value. |
41 | S An unsigned short value. | 40 | S An unsigned short value. |
@@ -221,7 +220,7 @@ Z_packer(struct packenv *env, int rep) | |||
221 | static void | 220 | static void |
222 | Z_unpacker(struct packenv *env, int rep) | 221 | Z_unpacker(struct packenv *env, int rep) |
223 | { | 222 | { |
224 | fprintf(env->fp, "%-*.*s", rep, rep, env->buf_base + env->buf_pos); | 223 | fprintf(env->fp, "%-*.*s", rep-1, rep-1, env->buf_base + env->buf_pos); |
225 | env->buf_pos += rep; | 224 | env->buf_pos += rep; |
226 | } | 225 | } |
227 | 226 | ||
@@ -672,18 +671,30 @@ packcomp(const char *s, char **endp) | |||
672 | struct packinst *head = NULL, *tail = NULL, *pi; | 671 | struct packinst *head = NULL, *tail = NULL, *pi; |
673 | struct packspec *ps; | 672 | struct packspec *ps; |
674 | int rep; | 673 | int rep; |
674 | int ec = 0; | ||
675 | 675 | ||
676 | while (s) { | 676 | errno = 0; |
677 | while (*s) { | ||
678 | if (isspace(*s)) { | ||
679 | ++s; | ||
680 | continue; | ||
681 | } | ||
677 | for (ps = packspec; ps->ch; ps++) | 682 | for (ps = packspec; ps->ch; ps++) |
678 | if (ps->ch == *s) | 683 | if (ps->ch == *s) |
679 | break; | 684 | break; |
680 | if (!ps->ch) | 685 | if (!ps->ch) { |
686 | ec = EINVAL; | ||
681 | break; | 687 | break; |
682 | if (getrep(s + 1, &s, &rep)) | 688 | } |
689 | if (getrep(s + 1, &s, &rep)) { | ||
690 | ec = EINVAL; | ||
683 | break; | 691 | break; |
692 | } | ||
684 | pi = malloc(sizeof(*pi)); | 693 | pi = malloc(sizeof(*pi)); |
685 | if (!pi) | 694 | if (!pi) { |
686 | return NULL; | 695 | ec = ENOMEM; |
696 | break; | ||
697 | } | ||
687 | pi->next = NULL; | 698 | pi->next = NULL; |
688 | pi->spec = ps; | 699 | pi->spec = ps; |
689 | pi->rep = rep; | 700 | pi->rep = rep; |
@@ -693,6 +704,11 @@ packcomp(const char *s, char **endp) | |||
693 | head = pi; | 704 | head = pi; |
694 | tail = pi; | 705 | tail = pi; |
695 | } | 706 | } |
707 | if (ec) { | ||
708 | packfree(head); | ||
709 | head = NULL; | ||
710 | errno = ec; | ||
711 | } | ||
696 | if (endp) | 712 | if (endp) |
697 | *endp = (char*) s; | 713 | *endp = (char*) s; |
698 | return head; | 714 | return head; |
diff --git a/tests/Makefile.am b/tests/Makefile.am index 4e3bc7b..f8f92d6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am | |||
@@ -40,6 +40,7 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac | |||
40 | ## ------------ ## | 40 | ## ------------ ## |
41 | 41 | ||
42 | TESTSUITE_AT = \ | 42 | TESTSUITE_AT = \ |
43 | pack.at\ | ||
43 | test01.at\ | 44 | test01.at\ |
44 | test02.at\ | 45 | test02.at\ |
45 | testsuite.at | 46 | testsuite.at |
diff --git a/tests/binpack.c b/tests/binpack.c index b54ed80..482e658 100644 --- a/tests/binpack.c +++ b/tests/binpack.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <stdlib.h> | 18 | #include <stdlib.h> |
19 | #include <stdio.h> | 19 | #include <stdio.h> |
20 | #include <stdarg.h> | 20 | #include <stdarg.h> |
21 | #include <string.h> | ||
22 | #include <errno.h> | ||
21 | #include "pack.h" | 23 | #include "pack.h" |
22 | #include "err.h" | 24 | #include "err.h" |
23 | 25 | ||
@@ -52,11 +54,12 @@ main(int argc, char **argv) | |||
52 | 54 | ||
53 | pi = packcomp(argv[0], &end); | 55 | pi = packcomp(argv[0], &end); |
54 | if (!pi) { | 56 | if (!pi) { |
55 | error("out of memory"); | 57 | if (errno == EINVAL) { |
56 | abort(); | 58 | error("%s: bad dataspec near %s", argv[0], end); |
57 | } | 59 | exit(1); |
58 | if (*end) { | 60 | } |
59 | error("compile error near %s", end); | 61 | |
62 | error("%s", strerror(errno)); | ||
60 | exit(1); | 63 | exit(1); |
61 | } | 64 | } |
62 | env = packenv_create(packsize(pi)); | 65 | env = packenv_create(packsize(pi)); |
diff --git a/tests/pack.at b/tests/pack.at new file mode 100644 index 0000000..0baf8e6 --- /dev/null +++ b/tests/pack.at | |||
@@ -0,0 +1,47 @@ | |||
1 | # This file is part of vmod-binlog testsuite -*- autotest -*- | ||
2 | # Copyright (C) 2013 Sergey Poznyakoff | ||
3 | # | ||
4 | # Vmod-binlog is free software; you can redistribute it and/or modify | ||
5 | # it under the terms of the GNU General Public License as published by | ||
6 | # the Free Software Foundation; either version 3, or (at your option) | ||
7 | # any later version. | ||
8 | # | ||
9 | # Vmod-binlog is distributed in the hope that it will be useful, | ||
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | # GNU General Public License for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License | ||
15 | # along with vmod-binlog. If not, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | m4_dnl TESTPACK(conv, args [, out]) | ||
18 | m4_define([TESTPACK], | ||
19 | [AT_SETUP($1) | ||
20 | AT_KEYWORDS([pack $1]) | ||
21 | AT_CHECK([binpack -- $1 $2 | binpack -d -- $1 | sed 's/ /_/g'],[0], | ||
22 | [m4_if([$3],,[m4_bpatsubst([$2],[ ],[_]) | ||
23 | ],[$3 | ||
24 | ])]) | ||
25 | AT_CLEANUP]) | ||
26 | |||
27 | AT_BANNER(Pack conversions) | ||
28 | |||
29 | TESTPACK(Z20, text, text_______________) | ||
30 | TESTPACK(c, A) | ||
31 | TESTPACK(s, 115) | ||
32 | TESTPACK(S, 115) | ||
33 | TESTPACK(l, 137) | ||
34 | TESTPACK(L, 137) | ||
35 | TESTPACK(q, 137) | ||
36 | TESTPACK(Q, 137) | ||
37 | TESTPACK(i, 137) | ||
38 | TESTPACK(i, -137) | ||
39 | TESTPACK(I, 137) | ||
40 | TESTPACK(n, 143) | ||
41 | TESTPACK(N, 2130706433) | ||
42 | TESTPACK(v, 143) | ||
43 | TESTPACK(V, 2130706433) | ||
44 | #TESTPACK(f, 1.456) | ||
45 | #TESTPACK(d, 1.456) | ||
46 | TESTPACK(L2, [24 67], 24_67) | ||
47 | TESTPACK(lZ5l2, [137 text -568 1025]) | ||
diff --git a/tests/test02.at b/tests/test02.at index 459a3cc..f1520a8 100644 --- a/tests/test02.at +++ b/tests/test02.at | |||
@@ -32,7 +32,7 @@ server s1 { | |||
32 | varnish v1 -vcl+backend { | 32 | varnish v1 -vcl+backend { |
33 | import binlog from "$abs_top_builddir/src/.libs/libvmod_binlog.so"; | 33 | import binlog from "$abs_top_builddir/src/.libs/libvmod_binlog.so"; |
34 | sub vcl_init { |