You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2018/07/13 22:06:47 UTC
[trafficserver] branch master updated: Add generic "guard" class
(PostScript) for exception and early function return safety.
This is an automated email from the ASF dual-hosted git repository.
amc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 77fb66b Add generic "guard" class (PostScript) for exception and early function return safety.
77fb66b is described below
commit 77fb66b114fd18defc9a0d161992de72c7ef30af
Author: Walter Karas <wk...@oath.com>
AuthorDate: Thu Jul 12 10:46:53 2018 -0500
Add generic "guard" class (PostScript) for exception and early function return safety.
---
lib/ts/Makefile.am | 4 +-
lib/ts/PostScript.h | 68 +++++++++++++++++++++++++++++++
lib/ts/unit-tests/test_PostScript.cc | 77 ++++++++++++++++++++++++++++++++++++
3 files changed, 148 insertions(+), 1 deletion(-)
diff --git a/lib/ts/Makefile.am b/lib/ts/Makefile.am
index e0bebb8..4b9d0be 100644
--- a/lib/ts/Makefile.am
+++ b/lib/ts/Makefile.am
@@ -20,7 +20,7 @@ include $(top_srcdir)/build/tidy.mk
library_includedir=$(includedir)/ts
-library_include_HEADERS = apidefs.h TextView.h
+library_include_HEADERS = apidefs.h TextView.h PostScript.h
noinst_PROGRAMS = mkdfa CompileParseRules
check_PROGRAMS = test_tsutil test_arena test_atomic test_freelist test_geometry test_List test_Map test_Vec test_X509HostnameValidator test_tslib
@@ -75,6 +75,7 @@ libtsutil_la_SOURCES = \
EventNotify.h \
fastlz.c \
fastlz.h \
+ PostScript.h \
Hash.cc \
HashFNV.cc \
HashFNV.h \
@@ -268,6 +269,7 @@ test_tslib_SOURCES = \
unit-tests/unit_test_main.cc \
unit-tests/test_BufferWriter.cc \
unit-tests/test_BufferWriterFormat.cc \
+ unit-tests/test_PostScript.cc \
unit-tests/test_ink_inet.cc \
unit-tests/test_IntrusiveDList.cc \
unit-tests/test_IntrusivePtr.cc \
diff --git a/lib/ts/PostScript.h b/lib/ts/PostScript.h
new file mode 100644
index 0000000..af91471
--- /dev/null
+++ b/lib/ts/PostScript.h
@@ -0,0 +1,68 @@
+/** @file
+
+ Generic "guard" class templates. The destructor calls a function object with arbitrary parameters. This utility is
+ available in both the core and plugins.
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#pragma once
+
+#include <tuple>
+
+namespace ts
+{
+// The destructor of this class calls the function object passed to its constructor, with the given arguments.
+// For example:
+// ts::PostScript g(TSHandleMLocRelease, bufp, parent, hdr);
+//
+// The release() member will prevent the call to the function upon destruction.
+//
+// Helpful in avoiding errors due to exception throws or error function return points, like the one that caused
+// Heartbleed.
+//
+template <typename Callable, typename... Args> class PostScript
+{
+public:
+ PostScript(Callable f, Args &&... args) : _f(f), _argsTuple(args...) {}
+
+ ~PostScript()
+ {
+ if (_armed) {
+ std::apply(_f, _argsTuple);
+ }
+ }
+
+ void
+ release()
+ {
+ _armed = false;
+ }
+
+ // No copying or moving.
+ PostScript(const PostScript &) = delete;
+ PostScript &operator=(const PostScript &) = delete;
+
+private:
+ bool _armed = true;
+ Callable _f;
+ std::tuple<Args...> _argsTuple;
+};
+
+} // end namespace ts
diff --git a/lib/ts/unit-tests/test_PostScript.cc b/lib/ts/unit-tests/test_PostScript.cc
new file mode 100644
index 0000000..1f95fec
--- /dev/null
+++ b/lib/ts/unit-tests/test_PostScript.cc
@@ -0,0 +1,77 @@
+/** @file
+
+ Unit tests for PostScript.h.
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#include "catch.hpp"
+#include <ts/PostScript.h>
+
+namespace
+{
+int f1Called;
+int f2Called;
+int f3Called;
+
+void
+f1(int a, double b, int c)
+{
+ ++f1Called;
+
+ REQUIRE(a == 1);
+ REQUIRE(b == 2.0);
+ REQUIRE(c == 3);
+}
+
+void
+f2(double a)
+{
+ ++f2Called;
+}
+
+void
+f3(int a, double b)
+{
+ ++f3Called;
+
+ REQUIRE(a == 5);
+ REQUIRE(b == 6.0);
+}
+
+} // namespace
+
+TEST_CASE("PostScript", "[PSC]")
+{
+ int lambdaCalled = 0;
+
+ {
+ ts::PostScript g1(f1, 1, 2.0, 3);
+ ts::PostScript g2(f2, 4);
+ ts::PostScript g3(f3, 5, 6.0);
+ ts::PostScript g4([&]() -> void { ++lambdaCalled; });
+
+ g2.release();
+ }
+
+ REQUIRE(f1Called == 1);
+ REQUIRE(f2Called == 0);
+ REQUIRE(f3Called == 1);
+ REQUIRE(lambdaCalled == 1);
+}