App/Toponaming: Linter cleanup of Base64 code

Does not address pointer arithmetic or array indexing complaints.
This commit is contained in:
Chris Hennes
2023-10-02 15:43:27 -05:00
parent 33abb7b5b1
commit 023ff7f388
5 changed files with 116 additions and 101 deletions

View File

@@ -24,29 +24,28 @@ freely, subject to the following restrictions:
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
Copyright (C) 2019 Zheng Lei (realthunder.dev@gmail.com)
Additional code Copyright (C) 2019 Zheng Lei (realthunder.dev@gmail.com)
* Added support of in-line transformation using boost iostream for memory efficiency
* Added support of in-line transformation using boost iostream for memory
efficiency
*/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <iostream>
#include <string>
#endif
#include "Base64.h"
// NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic, cppcoreguidelines-pro-bounds-constant-array-index, cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers)
static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static const std::array<char, 65> base64_chars {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/"};
const signed char* Base::base64_decode_table()
std::array<const signed char, Base::base64DecodeTableSize> Base::base64_decode_table()
{
static const signed char _table[] = {
static std::array<const signed char, Base::base64DecodeTableSize> _table = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -1, -2, -1, -1, // 0-15
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
-2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47
@@ -70,30 +69,30 @@ const signed char* Base::base64_decode_table()
std::size_t Base::base64_encode(char* out, void const* in, std::size_t in_len)
{
char* ret = out;
unsigned char const* bytes_to_encode = reinterpret_cast<unsigned char const*>(in);
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
auto const* bytes_to_encode = reinterpret_cast<unsigned char const*>(in); // NOLINT
int char3 {0};
int char4 {};
std::array<unsigned char,3> char_array_3{};
std::array<unsigned char,4> char_array_4{};
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
while ((in_len--) != 0U) {
char_array_3[char3++] = *(bytes_to_encode++);
if (char3 == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; (i < 4); i++) {
*ret++ = base64_chars[char_array_4[i]];
for (char3 = 0; (char3 < 4); char3++) {
*ret++ = base64_chars[char_array_4[char3]];
}
i = 0;
char3 = 0;
}
}
if (i) {
for (j = i; j < 3; j++) {
char_array_3[j] = '\0';
if (char3 != 0) {
for (char4 = char3; char4 < 3; char4++) {
char_array_3[char4] = '\0';
}
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
@@ -101,11 +100,11 @@ std::size_t Base::base64_encode(char* out, void const* in, std::size_t in_len)
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++) {
*ret++ = base64_chars[char_array_4[j]];
for (char4 = 0; (char4 < char3 + 1); char4++) {
*ret++ = base64_chars[char_array_4[char4]];
}
while ((i++ < 3)) {
while ((char3++ < 3)) {
*ret++ = '=';
}
}
@@ -116,47 +115,50 @@ std::size_t Base::base64_encode(char* out, void const* in, std::size_t in_len)
std::pair<std::size_t, std::size_t>
Base::base64_decode(void* _out, char const* in, std::size_t in_len)
{
unsigned char* out = reinterpret_cast<unsigned char*>(_out);
auto* out = reinterpret_cast<unsigned char*>(_out); // NOLINT
unsigned char* ret = out;
char const* input = in;
int i = 0;
int j = 0;
unsigned char char_array_4[4], char_array_3[3];
int byteCounter1 {0};
int byteCounter2 {};
std::array<unsigned char, 4> char_array_4{};
std::array<unsigned char, 3> char_array_3{};
static const signed char* table = base64_decode_table();
static auto table = base64_decode_table();
while (in_len-- && *in != '=') {
const signed char v = table[(int)(*in++)];
if (v < 0) {
while (((in_len--) != 0U) && *in != '=') {
const signed char lookup = table[static_cast<unsigned char>(*in++)];
if (lookup < 0) {
break;
}
char_array_4[i++] = (unsigned char)v;
if (i == 4) {
char_array_4[byteCounter1++] = (unsigned char)lookup;
if (byteCounter1 == 4) {
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++) {
*ret++ = char_array_3[i];
for (byteCounter1 = 0; (byteCounter1 < 3); byteCounter1++) {
*ret++ = char_array_3[byteCounter1];
}
i = 0;
byteCounter1 = 0;
}
}
if (i) {
for (j = i; j < 4; j++) {
char_array_4[j] = 0;
if (byteCounter1 != 0) {
for (byteCounter2 = byteCounter1; byteCounter2 < 4; byteCounter2++) {
char_array_4[byteCounter2] = 0;
}
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) {
*ret++ = char_array_3[j];
for (byteCounter2 = 0; (byteCounter2 < byteCounter1 - 1); byteCounter2++) {
*ret++ = char_array_3[byteCounter2];
}
}
return std::make_pair((std::size_t)(ret - out), (std::size_t)(in - input));
}
// NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic, cppcoreguidelines-pro-bounds-constant-array-index, cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers)

View File

@@ -31,6 +31,7 @@ Copyright (C) 2019 Zheng Lei (realthunder.dev@gmail.com)
#ifndef BASE_BASE64_H
#define BASE_BASE64_H
#include <array>
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/filtering_stream.hpp>
@@ -39,6 +40,10 @@ Copyright (C) 2019 Zheng Lei (realthunder.dev@gmail.com)
#include <string>
#include <vector>
#include "FCGlobal.h"
// NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic, cppcoreguidelines-pro-bounds-constant-array-index, cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers)
namespace Base
{
@@ -47,6 +52,8 @@ enum class Base64ErrorHandling
throws,
silent
};
static constexpr int base64DefaultBufferSize {80};
static constexpr size_t base64DecodeTableSize {256};
/// Returns the max bytes of a encoded base64 string
inline std::size_t base64_encode_size(std::size_t len)
@@ -76,7 +83,7 @@ BaseExport std::size_t base64_encode(char* out, void const* in, std::size_t len)
* data. White space (space, tab, vtab, CR and LF) characters are mapped
* to -2. Other invalid characters are mapped to -1.
*/
BaseExport const signed char* base64_decode_table();
BaseExport std::array<const signed char, base64DecodeTableSize> base64_decode_table();
/** Decode the input base64 string into binary data
* @param out: output buffer with minimum size of base64_encode(len)
@@ -136,25 +143,25 @@ inline std::size_t base64_decode(T& out, char const* in, std::size_t len)
/** Decode base64 string into binary data
* @param out: output binary data. Note that the data is not cleared before
* adding new content.
* @param s: input base64 string
* @param str: input base64 string
* @return Return the processed input length. Compare this with the
* argument \c len to check for error.
*/
template<typename T>
inline std::size_t base64_decode(T& out, std::string const& s)
inline std::size_t base64_decode(T& out, std::string const& str)
{
return base64_decode(out, s.c_str(), s.size());
return base64_decode(out, str.c_str(), str.size());
}
/** Decode base64 string into binary data
* @param out adding new content.
* @param s: input base64 string
* @param str: input base64 string
* @return Return the decoded binary data.
*/
inline std::string base64_decode(std::string const& s)
inline std::string base64_decode(std::string const& str)
{
std::string out;
base64_decode(out, s.c_str(), s.size());
base64_decode(out, str.c_str(), str.size());
return out;
}
@@ -167,7 +174,7 @@ namespace bio = boost::iostreams;
struct base64_encoder
{
typedef char char_type;
using char_type = char;
struct category: bio::multichar_output_filter_tag,
bio::closable_tag,
bio::optimally_buffered_tag
@@ -184,16 +191,16 @@ struct base64_encoder
std::streamsize optimal_buffer_size() const
{
return base64_decode_size(line_size);
return static_cast<std::streamsize>(base64_decode_size(line_size));
}
template<typename Device>
void close(Device& dev)
{
if (pending_size) {
base64_encode(buffer, pending, pending_size);
base64_encode(buffer, pending.data(), pending_size);
}
if (buffer.size()) {
if (!buffer.empty()) {
bio::write(dev, buffer.c_str(), buffer.size());
if (line_size) {
bio::put(dev, '\n');
@@ -206,27 +213,28 @@ struct base64_encoder
}
template<typename Device>
std::streamsize write(Device& dev, const char_type* s, std::streamsize n)
std::streamsize write(Device& dev, const char_type* str, std::streamsize n)
{
std::streamsize res = n;
if (pending_size) {
if (pending_size > 0) {
while (n && pending_size < 3) {
pending[pending_size++] = *s++;
pending[pending_size] = *str++;
++pending_size;
--n;
}
if (pending_size != 3) {
return res;
}
base64_encode(buffer, pending, 3);
base64_encode(buffer, pending.data(), 3);
}
pending_size = n % 3;
n = n / 3 * 3;
base64_encode(buffer, s, n);
s += n;
base64_encode(buffer, str, n);
str += n;
for (unsigned i = 0; i < pending_size; ++i) {
pending[i] = s[i];
pending[i] = str[i];
}
const char* buf = buffer.c_str();
@@ -250,7 +258,7 @@ struct base64_encoder
std::size_t line_size;
std::size_t pos = 0;
std::size_t pending_size = 0;
unsigned char pending[3];
std::array<unsigned char, 3> pending {};
std::string buffer;
};
@@ -261,7 +269,7 @@ struct base64_encoder
struct base64_decoder
{
typedef char char_type;
using char_type = char;
struct category: bio::multichar_input_filter_tag, bio::optimally_buffered_tag
{
};
@@ -278,13 +286,15 @@ struct base64_decoder
std::streamsize optimal_buffer_size() const
{
return base64_encode_size(line_size != 0U ? line_size : 1024);
static constexpr int defaultBufferSize {1024};
return static_cast<std::streamsize>(
base64_encode_size(line_size != 0U ? line_size : defaultBufferSize));
}
template<typename Device>
std::streamsize read(Device& dev, char_type* s, std::streamsize n)
std::streamsize read(Device& dev, char_type* str, std::streamsize n)
{
static const signed char* table = base64_decode_table();
static auto table = base64_decode_table();
if (!n) {
return 0;
@@ -294,7 +304,7 @@ struct base64_decoder
for (;;) {
while (pending_out < out_count) {
*s++ = char_array_3[pending_out++];
*str++ = char_array_3[pending_out++];
++count;
if (--n == 0) {
return count;
@@ -306,8 +316,8 @@ struct base64_decoder
}
for (;;) {
int d = bio::get(dev);
if (d < 0) {
int newChar = bio::get(dev);
if (newChar < 0) {
eof = true;
if (pending_in <= 1) {
if (pending_in == 1 && errHandling == Base64ErrorHandling::throws) {
@@ -319,21 +329,23 @@ struct base64_decoder
pending_in = 4;
}
else {
signed char c = table[d];
if (c < 0) {
if (c == -2 || errHandling == Base64ErrorHandling::silent) {
signed char decodedChar = table[newChar];
if (decodedChar < 0) {
if (decodedChar == -2 || errHandling == Base64ErrorHandling::silent) {
continue;
}
throw BOOST_IOSTREAMS_FAILURE("Invalid character in base64 string");
}
char_array_4[pending_in++] = (char)c;
char_array_4[pending_in++] = (char)decodedChar;
}
if (pending_in == 4) {
pending_out = pending_in = 0;
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] =
((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
char_array_3[0] =
static_cast<char>((char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4));
char_array_3[1] = static_cast<char>(((char_array_4[1] & 0xf) << 4)
+ ((char_array_4[2] & 0x3c) >> 2));
char_array_3[2] =
static_cast<char>(((char_array_4[2] & 0x3) << 6) + char_array_4[3]);
break;
}
}
@@ -342,10 +354,10 @@ struct base64_decoder
std::size_t line_size;
std::uint8_t pending_in = 0;
char char_array_4[4];
std::array<char, 4> char_array_4 {};
std::uint8_t pending_out = 3;
std::uint8_t out_count = 3;
char char_array_3[3];
std::array<char, 3> char_array_3 {};
Base64ErrorHandling errHandling;
bool eof = false;
};
@@ -358,13 +370,13 @@ struct base64_decoder
* @return A unique pointer to an output stream that can transforms the
* input binary data to base64 strings.
*/
inline std::unique_ptr<std::ostream> create_base64_encoder(std::ostream& out,
std::size_t line_size = 80)
inline std::unique_ptr<std::ostream>
create_base64_encoder(std::ostream& out, std::size_t line_size = base64DefaultBufferSize)
{
std::unique_ptr<std::ostream> res(new bio::filtering_ostream);
auto* f = static_cast<bio::filtering_ostream*>(res.get());
f->push(base64_encoder(line_size));
f->push(out);
auto* filteringStream = dynamic_cast<bio::filtering_ostream*>(res.get());
filteringStream->push(base64_encoder(line_size));
filteringStream->push(out);
return res;
}
@@ -376,13 +388,13 @@ inline std::unique_ptr<std::ostream> create_base64_encoder(std::ostream& out,
* @return A unique pointer to an output stream that can transforms the
* input binary data to base64 strings.
*/
inline std::unique_ptr<std::ostream> create_base64_encoder(const std::string& filepath,
std::size_t line_size = 80)
inline std::unique_ptr<std::ostream>
create_base64_encoder(const std::string& filepath, std::size_t line_size = base64DefaultBufferSize)
{
std::unique_ptr<std::ostream> res(new bio::filtering_ostream);
bio::filtering_ostream* f = static_cast<bio::filtering_ostream*>(res.get());
f->push(base64_encoder(line_size));
f->push(bio::file_sink(filepath));
auto* filteringStream = dynamic_cast<bio::filtering_ostream*>(res.get());
filteringStream->push(base64_encoder(line_size));
filteringStream->push(bio::file_sink(filepath));
return res;
}
@@ -398,13 +410,13 @@ inline std::unique_ptr<std::ostream> create_base64_encoder(const std::string& fi
*/
inline std::unique_ptr<std::istream>
create_base64_decoder(std::istream& in,
std::size_t line_size = 80,
std::size_t line_size = base64DefaultBufferSize,
Base64ErrorHandling errHandling = Base64ErrorHandling::silent)
{
std::unique_ptr<std::istream> res(new bio::filtering_istream);
bio::filtering_istream* f = static_cast<bio::filtering_istream*>(res.get());
f->push(base64_decoder(line_size, errHandling));
f->push(in);
auto* filteringStream = dynamic_cast<bio::filtering_istream*>(res.get());
filteringStream->push(base64_decoder(line_size, errHandling));
filteringStream->push(in);
return res;
}
@@ -424,16 +436,18 @@ create_base64_decoder(std::istream& in,
*/
inline std::unique_ptr<std::istream>
create_base64_decoder(const std::string& filepath,
std::size_t line_size = 80,
std::size_t line_size = base64DefaultBufferSize,
Base64ErrorHandling errHandling = Base64ErrorHandling::silent)
{
std::unique_ptr<std::istream> res(new bio::filtering_istream);
auto* f = static_cast<bio::filtering_istream*>(res.get());
f->push(base64_decoder(line_size, errHandling));
f->push(bio::file_source(filepath));
auto* filteringStream = dynamic_cast<bio::filtering_istream*>(res.get());
filteringStream->push(base64_decoder(line_size, errHandling));
filteringStream->push(bio::file_source(filepath));
return res;
}
} // namespace Base
// NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic, cppcoreguidelines-pro-bounds-constant-array-index, cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers)
#endif

View File

@@ -41,7 +41,6 @@ enum class CharStreamFormat {
Raw,
Base64Encoded
};
static constexpr int base64LineWidth {80};
/** File name unification
* This class handles everything related to file names

View File

@@ -372,7 +372,7 @@ std::istream& Base::XMLReader::beginCharStream(CharStreamFormat format)
CharStream = std::make_unique<boost::iostreams::filtering_istream>();
auto* filteringStream = dynamic_cast<boost::iostreams::filtering_istream*>(CharStream.get());
if(format == CharStreamFormat::Base64Encoded) {
filteringStream->push(base64_decoder(Base::base64LineWidth, Base64ErrorHandling::silent));
filteringStream->push(base64_decoder(Base::base64DefaultBufferSize, Base64ErrorHandling::silent));
}
filteringStream->push(boost::ref(*this));
return *CharStream;

View File

@@ -90,7 +90,7 @@ std::ostream& Writer::beginCharStream(CharStreamFormat format)
}
charStreamFormat = format;
if(format == CharStreamFormat::Base64Encoded) {
CharStream = create_base64_encoder(Stream(), Base::base64LineWidth);
CharStream = create_base64_encoder(Stream(), Base::base64DefaultBufferSize);
} else {
Stream() << "<![CDATA[";
CharStream = std::make_unique<boost::iostreams::filtering_ostream>();