aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-11-24 16:58:41 -0500
committerJack Lloyd <[email protected]>2017-11-24 17:04:24 -0500
commite39593993e28019edc09724705adc04ecd9671cb (patch)
tree9bd6727b376387f8124389545282d68114e939e7
parentd36213c9af8aa575a1a805a105e7bb3ddb647689 (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.cpp24
-rw-r--r--src/lib/filters/pipe.h12
-rw-r--r--src/tests/test_filters.cpp13
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); });