From 28a4f4173d0304bd1f56131eca966b89352afd7e Mon Sep 17 00:00:00 2001 From: EinMByte Date: Wed, 22 Jul 2015 16:43:11 +0200 Subject: [PATCH 1/6] Tests and documentation for base64. --- base64.cpp | 36 +++------------------------------- base64.h | 19 ++++++++++++++++++ filelist.mk | 2 +- tests/Data.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++++ tests/Identity.cpp | 1 - 5 files changed, 72 insertions(+), 35 deletions(-) create mode 100644 tests/Data.cpp diff --git a/base64.cpp b/base64.cpp index f5eac89b..28165365 100644 --- a/base64.cpp +++ b/base64.cpp @@ -45,23 +45,8 @@ namespace data static char P64 = '='; - /* - * - * ByteStreamToBase64 - * ------------------ - * - * Converts binary encoded data to BASE64 format. - * - */ - - size_t /* Number of bytes in the encoded buffer */ - ByteStreamToBase64 ( - const uint8_t * InBuffer, /* Input buffer, binary data */ - size_t InCount, /* Number of bytes in the input buffer */ - char * OutBuffer, /* output buffer */ - size_t len /* length of output buffer */ - ) + size_t ByteStreamToBase64(const uint8_t* InBuffer, size_t InCount, char* OutBuffer, size_t len) { unsigned char * ps; unsigned char * pd; @@ -124,23 +109,8 @@ namespace data return outCount; } - /* - * - * Base64ToByteStream - * ------------------ - * - * Converts BASE64 encoded data to binary format. If input buffer is - * not properly padded, buffer of negative length is returned - * - */ - size_t /* Number of output bytes */ - Base64ToByteStream ( - const char * InBuffer, /* BASE64 encoded buffer */ - size_t InCount, /* Number of input bytes */ - uint8_t * OutBuffer, /* output buffer length */ - size_t len /* length of output buffer */ - ) + size_t Base64ToByteStream(const char * InBuffer, size_t InCount, uint8_t* OutBuffer, size_t len) { unsigned char * ps; unsigned char * pd; @@ -154,7 +124,7 @@ namespace data if (isFirstTime) iT64Build(); n = InCount/4; m = InCount%4; - if (!m) + if(InCount && !m) outCount = 3*n; else { outCount = 0; diff --git a/base64.h b/base64.h index 027d62ba..74b9f7cf 100644 --- a/base64.h +++ b/base64.h @@ -9,7 +9,26 @@ namespace i2p namespace data { + + /* + * Base64 encodes an array of bytes. + * @return the number of characters in the output buffer + * @param InBuffer array of input bytes to be encoded + * @param InCount length of the input array + * @param OutBuffer array of output characters + * @param len length of the output buffer + */ size_t ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount, char * OutBuffer, size_t len); + + /** + * Decodes base 64 encoded data to an array of bytes. + * @return the number of bytes in the output buffer + * @param InBuffer array of input characters to be decoded + * @param InCount length of the input array + * @param OutBuffer array of output bytes + * @param len length of the output buffer + * @todo Do not return a negative value on failure, size_t could be unsigned. + */ size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len ); const char * GetBase64SubstitutionTable (); diff --git a/filelist.mk b/filelist.mk index f2aae727..5602970c 100644 --- a/filelist.mk +++ b/filelist.mk @@ -25,4 +25,4 @@ LIB_SRC := $(COMMON_SRC) \ api.cpp TESTS_SRC := $(COMMON_SRC) \ - tests/Utility.cpp tests/Identity.cpp + tests/Utility.cpp tests/Identity.cpp tests/Data.cpp diff --git a/tests/Data.cpp b/tests/Data.cpp new file mode 100644 index 00000000..cb9dd7bc --- /dev/null +++ b/tests/Data.cpp @@ -0,0 +1,49 @@ +#define BOOST_TEST_DYN_LINK + +#include +#include "../Identity.h" + +BOOST_AUTO_TEST_SUITE(DataTests) + +using namespace i2p::data; + +BOOST_AUTO_TEST_CASE(Base64EncodeEmpty) +{ + ByteStreamToBase64(nullptr, 0, nullptr, 0); +} + +BOOST_AUTO_TEST_CASE(Base64DecodeEmpty) +{ + Base64ToByteStream(nullptr, 0, nullptr, 0); +} + +BOOST_AUTO_TEST_CASE(Base64Encode) +{ + const uint8_t input[] = { + 0x53, 0xd3, 0x60, 0xfa, 0xf9, 0x58, 0xd0, 0x5e, 0x41, 0xa9, 0x6c, + 0xf1, 0x9f, 0xc4, 0xe, 0x23, 0x9b, 0xca, 0xb1, 0x61, 0xa7, 0x33, 0xcf, + 0x1f, 0x30 + }; + const char* output = "U9Ng-vlY0F5BqWzxn8QOI5vKsWGnM88fMA=="; + char result[36]; + ByteStreamToBase64(input, 25, result, 36); + BOOST_CHECK_EQUAL_COLLECTIONS(result, result + 36, output, output + 36); +} + +BOOST_AUTO_TEST_CASE(Base64Decode) +{ + const char* input = "U9Ng-vlY0F5BqWzxn8QOI5vKsWGnM88fMA=="; + const uint8_t output[] = { + 0x53, 0xd3, 0x60, 0xfa, 0xf9, 0x58, 0xd0, 0x5e, 0x41, 0xa9, 0x6c, + 0xf1, 0x9f, 0xc4, 0xe, 0x23, 0x9b, 0xca, 0xb1, 0x61, 0xa7, 0x33, 0xcf, + 0x1f, 0x30 + }; + uint8_t result[25]; + Base64ToByteStream(input, 36, result, 25); + BOOST_CHECK_EQUAL_COLLECTIONS(result, result + 25, output, output + 25); +} + + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/Identity.cpp b/tests/Identity.cpp index 597a2ba0..d74369a9 100644 --- a/tests/Identity.cpp +++ b/tests/Identity.cpp @@ -8,5 +8,4 @@ BOOST_AUTO_TEST_SUITE(IdentityTests) - BOOST_AUTO_TEST_SUITE_END() From 469981cce51598ab84135bb0f2c0b58da42e3a8c Mon Sep 17 00:00:00 2001 From: EinMByte Date: Thu, 23 Jul 2015 14:46:35 +0200 Subject: [PATCH 2/6] Tests and documentation for base32. --- base64.cpp | 10 +++++----- base64.h | 28 +++++++++++++++++++++++----- tests/Data.cpp | 37 +++++++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/base64.cpp b/base64.cpp index 28165365..715e11aa 100644 --- a/base64.cpp +++ b/base64.cpp @@ -33,16 +33,14 @@ namespace data } /* - * Reverse Substitution Table (built in run time) - */ - + * Reverse Substitution Table (built in run time) + */ static char iT64[256]; static int isFirstTime = 1; /* * Padding */ - static char P64 = '='; @@ -168,7 +166,6 @@ namespace data * * */ - static void iT64Build() { int i; @@ -208,6 +205,9 @@ namespace data size_t ByteStreamToBase32 (const uint8_t * inBuf, size_t len, char * outBuf, size_t outLen) { + if(!len) + return 0; // No data given + size_t ret = 0, pos = 1; int bits = 8, tmp = inBuf[0]; while (ret < outLen && (bits > 0 || pos < len)) diff --git a/base64.h b/base64.h index 74b9f7cf..938d82a8 100644 --- a/base64.h +++ b/base64.h @@ -12,28 +12,46 @@ namespace data /* * Base64 encodes an array of bytes. - * @return the number of characters in the output buffer + * @return the number of characters written to the output buffer * @param InBuffer array of input bytes to be encoded * @param InCount length of the input array - * @param OutBuffer array of output characters + * @param OutBuffer array to store output characters * @param len length of the output buffer */ size_t ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount, char * OutBuffer, size_t len); /** * Decodes base 64 encoded data to an array of bytes. - * @return the number of bytes in the output buffer + * @return the number of bytes written to the output buffer * @param InBuffer array of input characters to be decoded * @param InCount length of the input array - * @param OutBuffer array of output bytes + * @param OutBuffer array to store output bytes * @param len length of the output buffer * @todo Do not return a negative value on failure, size_t could be unsigned. */ size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len ); + const char * GetBase64SubstitutionTable (); + /** + * Decodes base 32 encoded data to an array of bytes. + * @return the number of bytes written to the output buffer + * @param inBuf array of input characters to be decoded + * @param len length of the input buffer + * @param outBuf array to store output bytes + * @param outLen length of the output array + */ size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen); - size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen); + + /** + * Base 32 encodes an array of bytes. + * @return the number of bytes written to the output buffer + * @param inBuf array of input bytes to be encoded + * @param len length of the input buffer + * @param outBuf array to store output characters + * @param outLen length of the output array + */ + size_t ByteStreamToBase32 (const uint8_t * inBuf, size_t len, char * outBuf, size_t outLen); } } diff --git a/tests/Data.cpp b/tests/Data.cpp index cb9dd7bc..17cec87c 100644 --- a/tests/Data.cpp +++ b/tests/Data.cpp @@ -9,12 +9,12 @@ using namespace i2p::data; BOOST_AUTO_TEST_CASE(Base64EncodeEmpty) { - ByteStreamToBase64(nullptr, 0, nullptr, 0); + BOOST_CHECK_EQUAL(ByteStreamToBase64(nullptr, 0, nullptr, 0), 0); } BOOST_AUTO_TEST_CASE(Base64DecodeEmpty) { - Base64ToByteStream(nullptr, 0, nullptr, 0); + BOOST_CHECK_EQUAL(Base64ToByteStream(nullptr, 0, nullptr, 0), 0); } BOOST_AUTO_TEST_CASE(Base64Encode) @@ -43,7 +43,40 @@ BOOST_AUTO_TEST_CASE(Base64Decode) BOOST_CHECK_EQUAL_COLLECTIONS(result, result + 25, output, output + 25); } +BOOST_AUTO_TEST_CASE(Base32EncodeEmpty) +{ + BOOST_CHECK_EQUAL(ByteStreamToBase32(nullptr, 0, nullptr, 0), 0); +} +BOOST_AUTO_TEST_CASE(Base32DecodeEmpty) +{ + BOOST_CHECK_EQUAL(Base32ToByteStream(nullptr, 0, nullptr, 0), 0); +} +BOOST_AUTO_TEST_CASE(Base32Encode) +{ + const uint8_t input[] = { + 0x53, 0xd3, 0x60, 0xfa, 0xf9, 0x58, 0xd0, 0x5e, 0x41, 0xa9, 0x6c, + 0xf1, 0x9f, 0xc4, 0xe, 0x23, 0x9b, 0xca, 0xb1, 0x61, 0xa7, 0x33, 0xcf, + 0x1f, 0x30 + }; + const char* output = "kpjwb6xzldif4qnjntyz7raoeon4vmlbu4z46hzq"; + char result[40]; + ByteStreamToBase32(input, 25, result, 40); + BOOST_CHECK_EQUAL_COLLECTIONS(result, result + 40, output, output + 40); +} + +BOOST_AUTO_TEST_CASE(Base32Decode) +{ + const char* input = "kpjwb6xzldif4qnjntyz7raoeon4vmlbu4z46hzq"; + const uint8_t output[] = { + 0x53, 0xd3, 0x60, 0xfa, 0xf9, 0x58, 0xd0, 0x5e, 0x41, 0xa9, 0x6c, + 0xf1, 0x9f, 0xc4, 0xe, 0x23, 0x9b, 0xca, 0xb1, 0x61, 0xa7, 0x33, 0xcf, + 0x1f, 0x30 + }; + uint8_t result[25]; + Base32ToByteStream(input, 40, result, 25); + BOOST_CHECK_EQUAL_COLLECTIONS(result, result + 25, output, output + 25); +} BOOST_AUTO_TEST_SUITE_END() From c3ec75756df18beb3b273c27f44ec1ea2ddd6c1e Mon Sep 17 00:00:00 2001 From: EinMByte Date: Thu, 23 Jul 2015 21:49:51 +0200 Subject: [PATCH 3/6] Also check the returned size in base64 tests. --- tests/Data.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/Data.cpp b/tests/Data.cpp index 17cec87c..552b1feb 100644 --- a/tests/Data.cpp +++ b/tests/Data.cpp @@ -26,8 +26,10 @@ BOOST_AUTO_TEST_CASE(Base64Encode) }; const char* output = "U9Ng-vlY0F5BqWzxn8QOI5vKsWGnM88fMA=="; char result[36]; - ByteStreamToBase64(input, 25, result, 36); + const size_t size = ByteStreamToBase64(input, 25, result, 36); + BOOST_CHECK_EQUAL_COLLECTIONS(result, result + 36, output, output + 36); + BOOST_CHECK_EQUAL(size, 36); } BOOST_AUTO_TEST_CASE(Base64Decode) @@ -39,8 +41,10 @@ BOOST_AUTO_TEST_CASE(Base64Decode) 0x1f, 0x30 }; uint8_t result[25]; - Base64ToByteStream(input, 36, result, 25); + const size_t size = Base64ToByteStream(input, 36, result, 25); + BOOST_CHECK_EQUAL_COLLECTIONS(result, result + 25, output, output + 25); + BOOST_CHECK_EQUAL(size, 25); } BOOST_AUTO_TEST_CASE(Base32EncodeEmpty) @@ -62,8 +66,10 @@ BOOST_AUTO_TEST_CASE(Base32Encode) }; const char* output = "kpjwb6xzldif4qnjntyz7raoeon4vmlbu4z46hzq"; char result[40]; - ByteStreamToBase32(input, 25, result, 40); + const size_t size = ByteStreamToBase32(input, 25, result, 40); + BOOST_CHECK_EQUAL_COLLECTIONS(result, result + 40, output, output + 40); + BOOST_CHECK_EQUAL(size, 40); } BOOST_AUTO_TEST_CASE(Base32Decode) @@ -75,8 +81,9 @@ BOOST_AUTO_TEST_CASE(Base32Decode) 0x1f, 0x30 }; uint8_t result[25]; - Base32ToByteStream(input, 40, result, 25); + const size_t size = Base32ToByteStream(input, 40, result, 25); BOOST_CHECK_EQUAL_COLLECTIONS(result, result + 25, output, output + 25); + BOOST_CHECK_EQUAL(size, 25); } BOOST_AUTO_TEST_SUITE_END() From 2bde6fc13b9a94f72dcbeeb0b73aca948dcb6a22 Mon Sep 17 00:00:00 2001 From: EinMByte Date: Fri, 24 Jul 2015 14:43:51 +0200 Subject: [PATCH 4/6] Fixes to GetMTUWindows and GetMTUWindowsIpv6 (thanks mlt). --- util.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util.cpp b/util.cpp index e9a9b5e9..39312acb 100644 --- a/util.cpp +++ b/util.cpp @@ -562,7 +562,7 @@ namespace net { return fallback; } - int GetMTUWindowsIpv6(sockaddr_in inputAddress, int fallback) + int GetMTUWindowsIpv6(sockaddr_in6 inputAddress, int fallback) { ULONG outBufLen = 0; PIP_ADAPTER_ADDRESSES pAddresses = nullptr; @@ -645,7 +645,7 @@ namespace net { return GetMTUWindowsIpv6(inputAddress, fallback); } else { LogPrint(eLogError, "GetMTU() has failed: address family is not supported"); - return result; + return fallback; } } From c612d21639800fc532e79c20866fa3f7fa951e1b Mon Sep 17 00:00:00 2001 From: EinMByte Date: Fri, 24 Jul 2015 15:13:09 +0200 Subject: [PATCH 5/6] Fix #229 by returning zero instead of -1. --- base64.cpp | 2 +- base64.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/base64.cpp b/base64.cpp index 715e11aa..cc0c7c21 100644 --- a/base64.cpp +++ b/base64.cpp @@ -133,7 +133,7 @@ namespace data while ( *ps-- == P64 ) outCount--; ps = (unsigned char *)InBuffer; - if (outCount > len) return -1; + if (outCount > len) return 0; pd = OutBuffer; auto endOfOutBuffer = OutBuffer + outCount; for ( i = 0; i < n; i++ ){ diff --git a/base64.h b/base64.h index 938d82a8..3c1ecb76 100644 --- a/base64.h +++ b/base64.h @@ -17,6 +17,7 @@ namespace data * @param InCount length of the input array * @param OutBuffer array to store output characters * @param len length of the output buffer + * @note zero is returned when the output buffer is too small */ size_t ByteStreamToBase64 (const uint8_t * InBuffer, size_t InCount, char * OutBuffer, size_t len); @@ -28,6 +29,7 @@ namespace data * @param OutBuffer array to store output bytes * @param len length of the output buffer * @todo Do not return a negative value on failure, size_t could be unsigned. + * @note zero is returned when the output buffer is too small */ size_t Base64ToByteStream (const char * InBuffer, size_t InCount, uint8_t * OutBuffer, size_t len ); @@ -40,6 +42,7 @@ namespace data * @param len length of the input buffer * @param outBuf array to store output bytes * @param outLen length of the output array + * @note zero is returned when the output buffer is too small */ size_t Base32ToByteStream (const char * inBuf, size_t len, uint8_t * outBuf, size_t outLen); @@ -50,6 +53,7 @@ namespace data * @param len length of the input buffer * @param outBuf array to store output characters * @param outLen length of the output array + * @note zero is returned when the output buffer is too small */ size_t ByteStreamToBase32 (const uint8_t * inBuf, size_t len, char * outBuf, size_t outLen); } From 7d38b1a9b935b0f4bc80110a164596e77366be48 Mon Sep 17 00:00:00 2001 From: EinMByte Date: Fri, 24 Jul 2015 15:32:47 +0200 Subject: [PATCH 6/6] Base64/32 tests for #229. --- tests/Data.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/Data.cpp b/tests/Data.cpp index 552b1feb..9e14ebfe 100644 --- a/tests/Data.cpp +++ b/tests/Data.cpp @@ -47,6 +47,20 @@ BOOST_AUTO_TEST_CASE(Base64Decode) BOOST_CHECK_EQUAL(size, 25); } +BOOST_AUTO_TEST_CASE(Base64EncodeBufferTooSmall) +{ + const uint8_t input[] = {0x53, 0xd3}; + char result[3]; + BOOST_CHECK_EQUAL(ByteStreamToBase64(input, 2, result, 3), 0); +} + +BOOST_AUTO_TEST_CASE(Base64DecodeBufferTooSmall) +{ + const char* input = "U9M="; + uint8_t result[1]; + BOOST_CHECK_EQUAL(Base64ToByteStream(input, 4, result, 1), 0); +} + BOOST_AUTO_TEST_CASE(Base32EncodeEmpty) { BOOST_CHECK_EQUAL(ByteStreamToBase32(nullptr, 0, nullptr, 0), 0); @@ -86,4 +100,18 @@ BOOST_AUTO_TEST_CASE(Base32Decode) BOOST_CHECK_EQUAL(size, 25); } +BOOST_AUTO_TEST_CASE(Base32EncodeBufferTooSmall) +{ + const uint8_t input[] = {0x53, 0xd3}; + char result[3]; + BOOST_CHECK_EQUAL(ByteStreamToBase64(input, 2, result, 3), 0); +} + +BOOST_AUTO_TEST_CASE(Base32DecodeBufferTooSmall) +{ + const char* input = "kpjq"; + uint8_t result[1]; + BOOST_CHECK_EQUAL(Base64ToByteStream(input, 4, result, 1), 0); +} + BOOST_AUTO_TEST_SUITE_END()