[PATCH 08/12] record: Add base64 filter class

Sebastian Huber sebastian.huber at embedded-brains.de
Mon Mar 16 10:50:28 UTC 2020


Update #3904.
---
 trace/record/client.h                |  20 +++++++
 trace/record/record-filter-base64.cc | 103 +++++++++++++++++++++++++++++++++++
 trace/wscript                        |   1 +
 3 files changed, 124 insertions(+)
 create mode 100644 trace/record/record-filter-base64.cc

diff --git a/trace/record/client.h b/trace/record/client.h
index 636fb0b..b4a0c26 100644
--- a/trace/record/client.h
+++ b/trace/record/client.h
@@ -112,6 +112,26 @@ class Filter {
   virtual bool Run(void** buf, size_t* n) = 0;
 };
 
+class Base64Filter : public Filter {
+ public:
+  Base64Filter() = default;
+
+  Base64Filter(const Base64Filter&) = default;
+
+  Base64Filter& operator=(const Base64Filter&) = default;
+
+  virtual ~Base64Filter() = default;
+
+  virtual bool Run(void** buf, size_t* n);
+
+ private:
+  int digits_ = 0;
+  bool seen_end_ = false;
+  int val_[4];
+
+  bool DecodeChar(int c, char **target);
+};
+
 class Client {
  public:
   Client() = default;
diff --git a/trace/record/record-filter-base64.cc b/trace/record/record-filter-base64.cc
new file mode 100644
index 0000000..12f4bab
--- /dev/null
+++ b/trace/record/record-filter-base64.cc
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: ISC */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2004, 2005, 2007, 2009  Internet Systems Consortium, Inc.
+ * ("ISC") Copyright (C) 1998-2001, 2003  Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "client.h"
+
+#include <cstring>
+
+static const char base64[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+
+bool Base64Filter::DecodeChar(int c, char **target) {
+  char* s;
+
+  if (seen_end_)
+    return false;
+  if ((s = std::strchr(const_cast<char*>(base64), c)) == NULL)
+    return false;
+  val_[digits_++] = s - base64;
+  if (digits_ == 4) {
+    int n;
+    unsigned char buf[3];
+    if (val_[0] == 64 || val_[1] == 64)
+      return false;
+    if (val_[2] == 64 && val_[3] != 64)
+      return false;
+    /*
+     * Check that bits that should be zero are.
+     */
+    if (val_[2] == 64 && (val_[1] & 0xf) != 0)
+      return false;
+    /*
+     * We don't need to test for val_[2] != 64 as
+     * the bottom two bits of 64 are zero.
+     */
+    if (val_[3] == 64 && (val_[2] & 0x3) != 0)
+      return false;
+    n = (val_[2] == 64) ? 1 : (val_[3] == 64) ? 2 : 3;
+    if (n != 3) {
+      seen_end_ = true;
+      if (val_[2] == 64)
+        val_[2] = 0;
+      if (val_[3] == 64)
+        val_[3] = 0;
+    }
+    buf[0] = (val_[0] << 2) | (val_[1] >> 4);
+    buf[1] = (val_[1] << 4) | (val_[2] >> 2);
+    buf[2] = (val_[2] << 6) | (val_[3]);
+    char *out = *target;
+    for (int i = 0; i < n; ++i) {
+      out[i] = buf[i];
+    }
+    *target = out + n;
+    digits_ = 0;
+  }
+  return true;
+}
+
+bool Base64Filter::Run(void** buf, size_t* n) {
+  char* begin = static_cast<char*>(*buf);
+  const char* in = begin;
+  const char* end = in + *n;
+
+  if (begin == end) {
+    return digits_ == 0;
+  }
+
+  char* target = begin;
+  while (in != end) {
+    int c = *in;
+    ++in;
+    if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
+      continue;
+    }
+
+    if (!DecodeChar(c, &target)) {
+      return false;
+    };
+  }
+
+  *n = static_cast<size_t>(target - begin);
+  return true;
+}
diff --git a/trace/wscript b/trace/wscript
index 3ded695..7e35f74 100644
--- a/trace/wscript
+++ b/trace/wscript
@@ -80,6 +80,7 @@ def build(bld):
                 source = ['record/record-client.c',
                           'record/record-text.c',
                           'record/record-client-base.cc',
+                          'record/record-filter-base64.cc',
                           'record/record-main-lttng.cc',
                           'record/inih/ini.c'],
                 includes = conf['includes'],
-- 
2.16.4



More information about the devel mailing list