diff options
author | Neal H. Walfield <neal@g10code.com> | 2015-08-17 11:56:42 +0200 |
---|---|---|
committer | Neal H. Walfield <neal@g10code.com> | 2015-08-20 14:16:24 +0200 |
commit | 827cc922d84d8113d4f13ebbed1314e03da5f7d2 (patch) | |
tree | 64589acc2ea9283826f3b17b270f15f0133c6f38 /common/t-iobuf.c | |
parent | common/iobuf.c: Flush the pipeline in iobuf_temp_to_buffer. (diff) | |
download | gnupg2-827cc922d84d8113d4f13ebbed1314e03da5f7d2.tar.xz gnupg2-827cc922d84d8113d4f13ebbed1314e03da5f7d2.zip |
common/iobuf.c: Buffered data should not be processed by new filters.
* common/iobuf.c (iobuf_push_filter2): If the pipeline is an output or
temp pipeline, the new filter shouldn't assume ownership of the old
head's internal buffer: the data was written before the filter was
added.
* common/t-iobuf.c (double_filter): New function.
(main): Add test cases for the above bug.
--
Signed-off-by: Neal H. Walfield <neal@g10code.com>.
Diffstat (limited to '')
-rw-r--r-- | common/t-iobuf.c | 104 |
1 files changed, 101 insertions, 3 deletions
diff --git a/common/t-iobuf.c b/common/t-iobuf.c index 0f21c351e..01c94a380 100644 --- a/common/t-iobuf.c +++ b/common/t-iobuf.c @@ -6,6 +6,8 @@ #include "iobuf.h" +/* Return every other byte. In particular, reads two bytes, returns + the second one. */ static int every_other_filter (void *opaque, int control, iobuf_t chain, byte *buf, size_t *len) @@ -42,6 +44,36 @@ every_other_filter (void *opaque, int control, return 0; } +static int +double_filter (void *opaque, int control, + iobuf_t chain, byte *buf, size_t *len) +{ + (void) opaque; + + if (control == IOBUFCTRL_DESC) + { + * (char **) buf = "double_filter"; + } + if (control == IOBUFCTRL_FLUSH) + { + int i; + + for (i = 0; i < *len; i ++) + { + int rc; + + rc = iobuf_writebyte (chain, buf[i]); + if (rc) + return rc; + rc = iobuf_writebyte (chain, buf[i]); + if (rc) + return rc; + } + } + + return 0; +} + struct content_filter_state { int pos; @@ -261,21 +293,87 @@ main (int argc, char *argv[]) c = iobuf_readbyte (iobuf); if (c == -1 && lastc == -1) { - printf("Two EOFs in a row. Done.\n"); + // printf("Two EOFs in a row. Done.\n"); + assert (n == 44); break; } lastc = c; if (c == -1) - printf("After %d bytes, got EOF.\n", n); + { + // printf("After %d bytes, got EOF.\n", n); + assert (n == 27 || n == 44); + } else { n ++; - printf ("%d: '%c' (%d)\n", n, c, c); + // printf ("%d: '%c' (%d)\n", n, c, c); } } } + /* Write some data to a temporary filter. Push a new filter. The + already written data should not be processed by the new + filter. */ + { + iobuf_t iobuf; + int rc; + char *content = "0123456789"; + char *content2 = "abc"; + char buffer[4096]; + int n; + + iobuf = iobuf_temp (); + assert (iobuf); + + rc = iobuf_write (iobuf, content, strlen (content)); + assert (rc == 0); + + rc = iobuf_push_filter (iobuf, double_filter, NULL); + assert (rc == 0); + + /* Include a NUL. */ + rc = iobuf_write (iobuf, content2, strlen (content2) + 1); + assert (rc == 0); + + n = iobuf_temp_to_buffer (iobuf, buffer, sizeof (buffer)); + printf ("Got %d bytes\n", n); + printf ("buffer: `"); + fwrite (buffer, n, 1, stdout); + fputc ('\'', stdout); + fputc ('\n', stdout); + + assert (n == strlen (content) + 2 * (strlen (content2) + 1)); + assert (strcmp (buffer, "0123456789aabbcc") == 0); + } + + { + iobuf_t iobuf; + int rc; + char *content = "0123456789"; + int n; + int c; + char buffer[strlen (content)]; + + iobuf = iobuf_temp_with_content (content, strlen (content)); + assert (iobuf); + + rc = iobuf_push_filter (iobuf, every_other_filter, NULL); + assert (rc == 0); + rc = iobuf_push_filter (iobuf, every_other_filter, NULL); + assert (rc == 0); + + for (n = 0; (c = iobuf_get (iobuf)) != -1; n ++) + { + // printf ("%d: `%c'\n", n, c); + buffer[n] = c; + } + + assert (n == 2); + assert (buffer[0] == '3'); + assert (buffer[1] == '7'); + } + return 0; } |