Skip to content

Commit ee502ee

Browse files
committed
swap base64 implementation to CRT
1 parent 2857dbc commit ee502ee

5 files changed

Lines changed: 53 additions & 139 deletions

File tree

prefetch_crt_dependency.sh

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
# SPDX-License-Identifier: Apache-2.0.
44

55
CRT_URI_PREFIX=https://codeload.github.com/awslabs
6-
CRT_URI=${CRT_URI_PREFIX}/aws-crt-cpp/zip/72f84bc327462f405c4994228fffe1eeb16cca72 # v0.42.2
6+
CRT_URI=${CRT_URI_PREFIX}/aws-crt-cpp/zip/0463563f9f656a493ec22ca962c2464bc8b831ab # v0.43.2
77

88
AWS_C_AUTH_URI=${CRT_URI_PREFIX}/aws-c-auth/zip/4b5d524bf1a511b05e0fffe5bdc51800770b9427 # v0.10.4
9-
AWS_C_CAL_URI=${CRT_URI_PREFIX}/aws-c-cal/zip/9edd8eac2b21ca6a04535b91d60d361c2f1bb60f # v0.9.14
9+
AWS_C_CAL_URI=${CRT_URI_PREFIX}/aws-c-cal/zip/8aa2a48a09f93c65d4cf06388e143a6584de6321 # v0.9.15
1010
AWS_C_COMMON_URI=${CRT_URI_PREFIX}/aws-c-common/zip/3c69b871dfa1815231802febf1bb6899f84cccdb # v0.14.3
1111
AWS_C_COMPRESSION_URI=${CRT_URI_PREFIX}/aws-c-compression/zip/d8264e64f698341eb03039b96b4f44702a9b3f83 # v0.3.2
1212
AWS_C_EVENT_STREAM_URI=${CRT_URI_PREFIX}/aws-c-event-stream/zip/51bef3c44e1058b1689751539170b2e0f589ccdb # v0.7.1
1313
AWS_C_HTTP_URI=${CRT_URI_PREFIX}/aws-c-http/zip/8aefd899fc3210bfd0e3fd414011a3cb708bf6e4 # v0.11.0
14-
AWS_C_IO_URI=${CRT_URI_PREFIX}/aws-c-io/zip/54350963b64dfc6c4b0ea623b08aa252aae3d7d7 # v0.27.4
14+
AWS_C_IO_URI=${CRT_URI_PREFIX}/aws-c-io/zip/e2946c99521fa12d285c9a0829c92b1bf713922b # v0.27.5
1515
AWS_C_MQTT_URI=${CRT_URI_PREFIX}/aws-c-mqtt/zip/2ef9605ec9c50bea3f921e08022ddd57eed70901 # v0.16.0
16-
AWS_C_S3_URI=${CRT_URI_PREFIX}/aws-c-s3/zip/1f29ef8871a27dc8b90325418780659bac534d71 # v0.13.1
17-
AWS_C_SDKUTILS_URI=${CRT_URI_PREFIX}/aws-c-sdkutils/zip/cb14fea362c82c995eebd34e2e96590ab4e0ed58 # v0.2.7
16+
AWS_C_S3_URI=${CRT_URI_PREFIX}/aws-c-s3/zip/a852faa2df3ab2b31fb4cfd64fd3379a2f4ae22e # v0.13.2
17+
AWS_C_SDKUTILS_URI=${CRT_URI_PREFIX}/aws-c-sdkutils/zip/528b9dfff4a804b334875ecf8a0471f7d1366f24 # v0.2.8
1818
AWS_CHECKSUMS_URI=${CRT_URI_PREFIX}/aws-checksums/zip/1d5f2f1f3e5d013aae8810878ceb5b3f6f258c4e # v0.2.10
19-
AWS_LC_URI=${CRT_URI_PREFIX}/aws-lc/zip/683ebde4bf3bcc016a9a710ad6b49c0c91b59161 # v5.2.0
20-
S2N_URI=${CRT_URI_PREFIX}/s2n/zip/f5f6c6c2ce2370de1aa3ade6899a7321d1127bb8 # v1.7.5
19+
AWS_LC_URI=${CRT_URI_PREFIX}/aws-lc/zip/f6acf748df0ea6157d55e640730b38d21a7751cd # v5.4.0
20+
S2N_URI=${CRT_URI_PREFIX}/s2n/zip/66b1c94d1dfc99b237427cbde230eca63bb8b89c # v1.7.6
2121

2222

2323
echo "Removing CRT"

src/aws-cpp-sdk-core/include/aws/core/utils/base64/Base64.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,6 @@ namespace Aws
5757
* Calculates the length of an encoded base64 string based on the buffer being encoded
5858
*/
5959
static size_t CalculateBase64EncodedLength(const ByteBuffer& buffer);
60-
61-
private:
62-
char m_mimeBase64EncodingTable[64];
63-
uint8_t m_mimeBase64DecodingTable[256];
64-
6560
};
6661

6762
} // namespace Base64

src/aws-cpp-sdk-core/source/utils/base64/Base64.cpp

Lines changed: 26 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -3,146 +3,46 @@
33
* SPDX-License-Identifier: Apache-2.0.
44
*/
55

6+
#include <aws/core/utils/UnreferencedParam.h>
67
#include <aws/core/utils/base64/Base64.h>
7-
#include <cstring>
8+
#include <aws/crt/Types.h>
89

910
using namespace Aws::Utils::Base64;
1011

11-
static const uint8_t SENTINEL_VALUE = 255;
12-
static const char BASE64_ENCODING_TABLE_MIME[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
12+
namespace Aws {
13+
namespace Utils {
14+
namespace Base64 {
1315

14-
namespace Aws
15-
{
16-
namespace Utils
17-
{
18-
namespace Base64
19-
{
20-
21-
Base64::Base64(const char *encodingTable)
22-
{
23-
if(encodingTable == nullptr)
24-
{
25-
encodingTable = BASE64_ENCODING_TABLE_MIME;
26-
}
27-
28-
size_t encodingTableLength = strlen(encodingTable);
29-
if(encodingTableLength != 64)
30-
{
31-
encodingTable = BASE64_ENCODING_TABLE_MIME;
32-
encodingTableLength = 64;
33-
}
34-
35-
memcpy(m_mimeBase64EncodingTable, encodingTable, encodingTableLength);
36-
37-
memset((void *)m_mimeBase64DecodingTable, 0, 256);
38-
39-
for(uint32_t i = 0; i < encodingTableLength; ++i)
40-
{
41-
uint32_t index = static_cast<uint32_t>(m_mimeBase64EncodingTable[i]);
42-
m_mimeBase64DecodingTable[index] = static_cast<uint8_t>(i);
43-
}
44-
45-
m_mimeBase64DecodingTable[(uint32_t)'='] = SENTINEL_VALUE;
16+
namespace {
17+
Aws::Crt::ByteCursor AsCursor(const Aws::Utils::ByteBuffer& buffer) {
18+
return Aws::Crt::ByteCursorFromArray(buffer.GetUnderlyingData(), buffer.GetLength());
4619
}
4720

48-
Aws::String Base64::Encode(const Aws::Utils::ByteBuffer& buffer) const
49-
{
50-
size_t bufferLength = buffer.GetLength();
51-
size_t blockCount = (bufferLength + 2) / 3;
52-
size_t remainderCount = (bufferLength % 3);
53-
54-
Aws::String outputString;
55-
outputString.reserve(CalculateBase64EncodedLength(buffer));
56-
57-
for(size_t i = 0; i < bufferLength; i += 3 )
58-
{
59-
uint32_t block = buffer[ i ];
60-
61-
block <<= 8;
62-
if (i + 1 < bufferLength)
63-
{
64-
block = block | buffer[ i + 1 ];
65-
}
66-
67-
block <<= 8;
68-
if (i + 2 < bufferLength)
69-
{
70-
block = block | buffer[ i + 2 ];
71-
}
72-
73-
outputString.push_back(m_mimeBase64EncodingTable[(block >> 18) & 0x3F]);
74-
outputString.push_back(m_mimeBase64EncodingTable[(block >> 12) & 0x3F]);
75-
outputString.push_back(m_mimeBase64EncodingTable[(block >> 6) & 0x3F]);
76-
outputString.push_back(m_mimeBase64EncodingTable[block & 0x3F]);
77-
}
78-
79-
if(remainderCount > 0)
80-
{
81-
outputString[blockCount * 4 - 1] = '=';
82-
if(remainderCount == 1)
83-
{
84-
outputString[blockCount * 4 - 2] = '=';
85-
}
86-
}
87-
88-
return outputString;
21+
Aws::Crt::ByteCursor AsCursor(const Aws::String& str) {
22+
return Aws::Crt::ByteCursorFromArray(reinterpret_cast<const uint8_t*>(str.data()), str.length());
8923
}
24+
} // namespace
9025

91-
Aws::Utils::ByteBuffer Base64::Decode(const Aws::String& str) const
92-
{
93-
size_t decodedLength = CalculateBase64DecodedLength(str);
94-
95-
Aws::Utils::ByteBuffer buffer(decodedLength);
96-
97-
const char* rawString = str.c_str();
98-
size_t blockCount = str.length() / 4;
99-
for(size_t i = 0; i < blockCount; ++i)
100-
{
101-
size_t stringIndex = i * 4;
26+
Base64::Base64(const char* encodingTable) { AWS_UNREFERENCED_PARAM(encodingTable); }
10227

103-
uint32_t value1 = m_mimeBase64DecodingTable[uint32_t(rawString[stringIndex])];
104-
uint32_t value2 = m_mimeBase64DecodingTable[uint32_t(rawString[++stringIndex])];
105-
uint32_t value3 = m_mimeBase64DecodingTable[uint32_t(rawString[++stringIndex])];
106-
uint32_t value4 = m_mimeBase64DecodingTable[uint32_t(rawString[++stringIndex])];
107-
108-
size_t bufferIndex = i * 3;
109-
buffer[bufferIndex] = static_cast<uint8_t>((value1 << 2) | ((value2 >> 4) & 0x03));
110-
if(value3 != SENTINEL_VALUE)
111-
{
112-
buffer[++bufferIndex] = static_cast<uint8_t>(((value2 << 4) & 0xF0) | ((value3 >> 2) & 0x0F));
113-
if(value4 != SENTINEL_VALUE)
114-
{
115-
buffer[++bufferIndex] = static_cast<uint8_t>((value3 & 0x03) << 6 | value4);
116-
}
117-
}
118-
}
119-
120-
return buffer;
28+
Aws::String Base64::Encode(const Aws::Utils::ByteBuffer& buffer) const {
29+
const auto encoded = Aws::Crt::Base64Encode(AsCursor(buffer));
30+
return {encoded.data(), encoded.size()};
12131
}
12232

123-
size_t Base64::CalculateBase64DecodedLength(const Aws::String& b64input)
124-
{
125-
const size_t len = b64input.length();
126-
if(len < 2)
127-
{
128-
return 0;
129-
}
130-
131-
size_t padding = 0;
132-
133-
if (b64input[len - 1] == '=' && b64input[len - 2] == '=') //last two chars are =
134-
padding = 2;
135-
else if (b64input[len - 1] == '=') //last char is =
136-
padding = 1;
33+
Aws::Utils::ByteBuffer Base64::Decode(const Aws::String& str) const {
34+
const auto decoded = Aws::Crt::Base64Decode(AsCursor(str));
35+
return {decoded.data(), decoded.size()};
36+
}
13737

138-
return (len * 3 / 4 - padding);
38+
size_t Base64::CalculateBase64EncodedLength(const Aws::Utils::ByteBuffer& buffer) {
39+
return Aws::Crt::Base64EncodedLength(AsCursor(buffer));
13940
}
14041

141-
size_t Base64::CalculateBase64EncodedLength(const Aws::Utils::ByteBuffer& buffer)
142-
{
143-
return 4 * ((buffer.GetLength() + 2) / 3);
42+
size_t Base64::CalculateBase64DecodedLength(const Aws::String& b64input) {
43+
return Aws::Crt::Base64DecodedLength(AsCursor(b64input));
14444
}
14545

146-
} // namespace Base64
147-
} // namespace Utils
148-
} // namespace Aws
46+
} // namespace Base64
47+
} // namespace Utils
48+
} // namespace Aws

tests/aws-cpp-sdk-core-tests/utils/HashingUtilsTest.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <aws/testing/AwsCppSdkGTestSuite.h>
77

88
#include <aws/core/utils/HashingUtils.h>
9+
#include <aws/core/utils/base64/Base64.h>
910
#include <aws/core/utils/memory/stl/AWSStringStream.h>
1011

1112

@@ -68,6 +69,24 @@ TEST_F(HashingUtilsTest, TestBase64Decoding)
6869
ASSERT_EQ(ByteBuffer((unsigned char*) "foobar", 6), test7);
6970
}
7071

72+
TEST_F(HashingUtilsTest, TestBase64DecodeNeverWritesMoreThanCalculatedLength)
73+
{
74+
Aws::Vector<Aws::String> inputs = {"", "X", "Zg==", "Zm8=", "Zm9v", "Zm9vYg==", "Zm9vYmE=", "Zm9vYmFy",
75+
"AAAA=", "AAAAA=", "AAAAAA=", "AAAAAAA=", "AB=D", "=", "==", "===", "====",
76+
"A===", "AA==", "AAA=", "//++", "AAAA"};
77+
for (int byte = 0x80; byte <= 0xFF; ++byte)
78+
{
79+
inputs.emplace_back(Aws::String{static_cast<char>(byte)} + "AAA");
80+
}
81+
82+
for (const auto& input : inputs)
83+
{
84+
ASSERT_LE(HashingUtils::Base64Decode(input).GetLength(),
85+
Aws::Utils::Base64::Base64::CalculateBase64DecodedLength(input))
86+
<< "input: " << input;
87+
}
88+
}
89+
7190
TEST_F(HashingUtilsTest, TestHexEncodingDecoding)
7291
{
7392
unsigned char beforeHexEncoding[32] =

0 commit comments

Comments
 (0)