diff options
author | Jack Lloyd <[email protected]> | 2017-11-24 16:58:41 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-11-24 17:04:24 -0500 |
commit | e39593993e28019edc09724705adc04ecd9671cb (patch) | |
tree | 9bd6727b376387f8124389545282d68114e939e7 | |
parent | d36213c9af8aa575a1a805a105e7bb3ddb647689 (diff) |
Add Pipe::append_filter
Similar to append but it only allows modfication before start_msg.
See GH #1306
-rw-r--r-- | src/lib/filters/pipe.cpp | 24 | ||||
-rw-r--r-- | src/lib/filters/pipe.h | 12 | ||||
-rw-r--r-- | src/tests/test_filters.cpp | 13 |
3 files changed, 36 insertions, 13 deletions
diff --git a/src/lib/filters/pipe.cpp b/src/lib/filters/pipe.cpp index ff3cb599b..ed6abbad8 100644 --- a/src/lib/filters/pipe.cpp +++ b/src/lib/filters/pipe.cpp @@ -40,7 +40,10 @@ Pipe::Pipe(Filter* f1, Filter* f2, Filter* f3, Filter* f4) : */ Pipe::Pipe(std::initializer_list<Filter*> args) { - init(); + m_outputs.reset(new Output_Buffers); + m_pipe = nullptr; + m_default_read = 0; + m_inside_msg = false; for(auto i = args.begin(); i != args.end(); ++i) do_append(*i); @@ -55,17 +58,6 @@ Pipe::~Pipe() } /* -* Initialize the Pipe -*/ -void Pipe::init() - { - m_outputs.reset(new Output_Buffers); - m_pipe = nullptr; - m_default_read = 0; - m_inside_msg = false; - } - -/* * Reset the Pipe */ void Pipe::reset() @@ -214,6 +206,14 @@ void Pipe::append(Filter* filter) do_append(filter); } +void Pipe::append_filter(Filter* filter) + { + if(m_outputs->message_count() != 0) + throw Invalid_State("Cannot call Pipe::append_filter after start_msg"); + + do_append(filter); + } + /* * Append a Filter to the Pipe */ diff --git a/src/lib/filters/pipe.h b/src/lib/filters/pipe.h index cd446bd7e..9ba299024 100644 --- a/src/lib/filters/pipe.h +++ b/src/lib/filters/pipe.h @@ -295,6 +295,17 @@ class BOTAN_PUBLIC_API(2,0) Pipe final : public DataSource void reset(); /** + * Append a new filter onto the filter sequence. This may only be + * called immediately after initial construction, before _any_ + * calls to start_msg have been made. + * + * This function (unlike append) is not deprecated, as it allows + * only modification of the pipe at initialization (before use) + * rather than after messages have been processed. + */ + void append_filter(Filter* filt); + + /** * Construct a Pipe of up to four filters. The filters are set up * in the same order as the arguments. */ @@ -312,7 +323,6 @@ class BOTAN_PUBLIC_API(2,0) Pipe final : public DataSource ~Pipe(); private: - void init(); void destruct(Filter*); void do_append(Filter* filt); void find_endpoints(Filter*); diff --git a/src/tests/test_filters.cpp b/src/tests/test_filters.cpp index 26d13e0bc..b8a4ee9f0 100644 --- a/src/tests/test_filters.cpp +++ b/src/tests/test_filters.cpp @@ -198,6 +198,7 @@ class Filter_Tests final : public Test Botan::Pipe pipe; + pipe.append_filter(nullptr); // ignored pipe.append(nullptr); // ignored pipe.prepend(nullptr); // ignored pipe.pop(); // empty pipe, so ignored @@ -213,11 +214,19 @@ class Filter_Tests final : public Test "Invalid argument Pipe::prepend: SecureQueue cannot be used", [&]() { pipe.prepend(queue_filter.get()); }); + pipe.append_filter(new Botan::BitBucket); // succeeds + pipe.pop(); + pipe.start_msg(); std::unique_ptr<Botan::Filter> filter(new Botan::BitBucket); // now inside a message, cannot modify pipe structure + + result.test_throws("pipe error", + "Cannot call Pipe::append_filter after start_msg", + [&]() { pipe.append_filter(filter.get()); }); + result.test_throws("pipe error", "Cannot append to a Pipe while it is processing", [&]() { pipe.append(filter.get()); }); @@ -233,6 +242,10 @@ class Filter_Tests final : public Test pipe.end_msg(); result.test_throws("pipe error", + "Cannot call Pipe::append_filter after start_msg", + [&]() { pipe.append_filter(filter.get()); }); + + result.test_throws("pipe error", "Invalid argument Pipe::read: Invalid message number 100", [&]() { uint8_t b; size_t got = pipe.read(&b, 1, 100); BOTAN_UNUSED(got); }); |