From 5bc9f73a48367b3fff95689e3467be1b9e1f97f8 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 16 Mar 2020 08:05:41 +0100 Subject: record: Add base64 filter class 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 (limited to 'trace') 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 + +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(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(*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(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'], -- cgit v1.2.3