You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-11-06 08:49:29 +02:00
Use switch rather than if-else for encoding types.
This is more efficient and the error case can be an assert rather than a runtime error. For extra safety initialize destinationSize to SIZE_MAX to increase the chances of an error if the switch fails.
This commit is contained in:
@@ -11,10 +11,10 @@ Binary to String Encode/Decode
|
|||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Macro to handle invalid encode type errors
|
Assert that encoding type is valid. This needs to be kept up to date with the last item in the enum.
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
#define ENCODE_TYPE_INVALID_ERROR(encodeType) \
|
#define ASSERT_ENCODE_TYPE_VALID(type) \
|
||||||
THROW_FMT(AssertError, "invalid encode type %u", encodeType);
|
ASSERT(type <= encodeBase64);
|
||||||
|
|
||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Base64 encoding/decoding
|
Base64 encoding/decoding
|
||||||
@@ -228,85 +228,101 @@ decodeToBinSizeBase64(const char *source)
|
|||||||
Generic encoding/decoding
|
Generic encoding/decoding
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
void
|
void
|
||||||
encodeToStr(EncodeType encodeType, const unsigned char *source, size_t sourceSize, char *destination)
|
encodeToStr(EncodeType type, const unsigned char *source, size_t sourceSize, char *destination)
|
||||||
{
|
{
|
||||||
FUNCTION_TEST_BEGIN();
|
FUNCTION_TEST_BEGIN();
|
||||||
FUNCTION_TEST_PARAM(ENUM, encodeType);
|
FUNCTION_TEST_PARAM(ENUM, type);
|
||||||
FUNCTION_TEST_PARAM_P(UCHARDATA, source);
|
FUNCTION_TEST_PARAM_P(UCHARDATA, source);
|
||||||
FUNCTION_TEST_PARAM(SIZE, sourceSize);
|
FUNCTION_TEST_PARAM(SIZE, sourceSize);
|
||||||
FUNCTION_TEST_PARAM_P(CHARDATA, destination);
|
FUNCTION_TEST_PARAM_P(CHARDATA, destination);
|
||||||
FUNCTION_TEST_END();
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
if (encodeType == encodeBase64)
|
ASSERT_ENCODE_TYPE_VALID(type);
|
||||||
encodeToStrBase64(source, sourceSize, destination);
|
|
||||||
else
|
switch (type)
|
||||||
ENCODE_TYPE_INVALID_ERROR(encodeType);
|
{
|
||||||
|
case encodeBase64:
|
||||||
|
encodeToStrBase64(source, sourceSize, destination);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN_VOID();
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
size_t
|
size_t
|
||||||
encodeToStrSize(EncodeType encodeType, size_t sourceSize)
|
encodeToStrSize(EncodeType type, size_t sourceSize)
|
||||||
{
|
{
|
||||||
FUNCTION_TEST_BEGIN();
|
FUNCTION_TEST_BEGIN();
|
||||||
FUNCTION_TEST_PARAM(ENUM, encodeType);
|
FUNCTION_TEST_PARAM(ENUM, type);
|
||||||
FUNCTION_TEST_PARAM(SIZE, sourceSize);
|
FUNCTION_TEST_PARAM(SIZE, sourceSize);
|
||||||
FUNCTION_TEST_END();
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
size_t destinationSize = 0;
|
ASSERT_ENCODE_TYPE_VALID(type);
|
||||||
|
|
||||||
if (encodeType == encodeBase64)
|
size_t destinationSize = SIZE_MAX;
|
||||||
destinationSize = encodeToStrSizeBase64(sourceSize);
|
|
||||||
else
|
switch (type)
|
||||||
ENCODE_TYPE_INVALID_ERROR(encodeType);
|
{
|
||||||
|
case encodeBase64:
|
||||||
|
destinationSize = encodeToStrSizeBase64(sourceSize);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(destinationSize);
|
FUNCTION_TEST_RETURN(destinationSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
void
|
void
|
||||||
decodeToBin(EncodeType encodeType, const char *source, unsigned char *destination)
|
decodeToBin(EncodeType type, const char *source, unsigned char *destination)
|
||||||
{
|
{
|
||||||
FUNCTION_TEST_BEGIN();
|
FUNCTION_TEST_BEGIN();
|
||||||
FUNCTION_TEST_PARAM(ENUM, encodeType);
|
FUNCTION_TEST_PARAM(ENUM, type);
|
||||||
FUNCTION_TEST_PARAM(STRINGZ, source);
|
FUNCTION_TEST_PARAM(STRINGZ, source);
|
||||||
FUNCTION_TEST_PARAM_P(UCHARDATA, destination);
|
FUNCTION_TEST_PARAM_P(UCHARDATA, destination);
|
||||||
FUNCTION_TEST_END();
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
if (encodeType == encodeBase64)
|
ASSERT_ENCODE_TYPE_VALID(type);
|
||||||
decodeToBinBase64(source, destination);
|
|
||||||
else
|
switch (type)
|
||||||
ENCODE_TYPE_INVALID_ERROR(encodeType);
|
{
|
||||||
|
case encodeBase64:
|
||||||
|
decodeToBinBase64(source, destination);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN_VOID();
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
size_t
|
size_t
|
||||||
decodeToBinSize(EncodeType encodeType, const char *source)
|
decodeToBinSize(EncodeType type, const char *source)
|
||||||
{
|
{
|
||||||
FUNCTION_TEST_BEGIN();
|
FUNCTION_TEST_BEGIN();
|
||||||
FUNCTION_TEST_PARAM(ENUM, encodeType);
|
FUNCTION_TEST_PARAM(ENUM, type);
|
||||||
FUNCTION_TEST_PARAM(STRINGZ, source);
|
FUNCTION_TEST_PARAM(STRINGZ, source);
|
||||||
FUNCTION_TEST_END();
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
size_t destinationSize = 0;
|
ASSERT_ENCODE_TYPE_VALID(type);
|
||||||
|
|
||||||
if (encodeType == encodeBase64)
|
size_t destinationSize = SIZE_MAX;
|
||||||
destinationSize = decodeToBinSizeBase64(source);
|
|
||||||
else
|
switch (type)
|
||||||
ENCODE_TYPE_INVALID_ERROR(encodeType);
|
{
|
||||||
|
case encodeBase64:
|
||||||
|
destinationSize = decodeToBinSizeBase64(source);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN(destinationSize);
|
FUNCTION_TEST_RETURN(destinationSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
bool
|
bool
|
||||||
decodeToBinValid(EncodeType encodeType, const char *source)
|
decodeToBinValid(EncodeType type, const char *source)
|
||||||
{
|
{
|
||||||
FUNCTION_TEST_BEGIN();
|
FUNCTION_TEST_BEGIN();
|
||||||
FUNCTION_TEST_PARAM(ENUM, encodeType);
|
FUNCTION_TEST_PARAM(ENUM, type);
|
||||||
FUNCTION_TEST_PARAM(STRINGZ, source);
|
FUNCTION_TEST_PARAM(STRINGZ, source);
|
||||||
FUNCTION_TEST_END();
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
@@ -314,7 +330,7 @@ decodeToBinValid(EncodeType encodeType, const char *source)
|
|||||||
|
|
||||||
TRY_BEGIN()
|
TRY_BEGIN()
|
||||||
{
|
{
|
||||||
decodeToBinValidate(encodeType, source);
|
decodeToBinValidate(type, source);
|
||||||
}
|
}
|
||||||
CATCH(FormatError)
|
CATCH(FormatError)
|
||||||
{
|
{
|
||||||
@@ -327,17 +343,21 @@ decodeToBinValid(EncodeType encodeType, const char *source)
|
|||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
void
|
void
|
||||||
decodeToBinValidate(EncodeType encodeType, const char *source)
|
decodeToBinValidate(EncodeType type, const char *source)
|
||||||
{
|
{
|
||||||
FUNCTION_TEST_BEGIN();
|
FUNCTION_TEST_BEGIN();
|
||||||
FUNCTION_TEST_PARAM(ENUM, encodeType);
|
FUNCTION_TEST_PARAM(ENUM, type);
|
||||||
FUNCTION_TEST_PARAM(STRINGZ, source);
|
FUNCTION_TEST_PARAM(STRINGZ, source);
|
||||||
FUNCTION_TEST_END();
|
FUNCTION_TEST_END();
|
||||||
|
|
||||||
if (encodeType == encodeBase64)
|
ASSERT_ENCODE_TYPE_VALID(type);
|
||||||
decodeToBinValidateBase64(source);
|
|
||||||
else
|
switch (type)
|
||||||
ENCODE_TYPE_INVALID_ERROR(encodeType);
|
{
|
||||||
|
case encodeBase64:
|
||||||
|
decodeToBinValidateBase64(source);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
FUNCTION_TEST_RETURN_VOID();
|
FUNCTION_TEST_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,21 +20,21 @@ typedef enum
|
|||||||
Functions
|
Functions
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
// Encode binary data to a printable string
|
// Encode binary data to a printable string
|
||||||
void encodeToStr(EncodeType encodeType, const unsigned char *source, size_t sourceSize, char *destination);
|
void encodeToStr(EncodeType type, const unsigned char *source, size_t sourceSize, char *destination);
|
||||||
|
|
||||||
// Size of the string returned by encodeToStr()
|
// Size of the string returned by encodeToStr()
|
||||||
size_t encodeToStrSize(EncodeType encodeType, size_t sourceSize);
|
size_t encodeToStrSize(EncodeType type, size_t sourceSize);
|
||||||
|
|
||||||
// Decode a string to binary data
|
// Decode a string to binary data
|
||||||
void decodeToBin(EncodeType encodeType, const char *source, unsigned char *destination);
|
void decodeToBin(EncodeType type, const char *source, unsigned char *destination);
|
||||||
|
|
||||||
// Size of the binary data returned by decodeToBin()
|
// Size of the binary data returned by decodeToBin()
|
||||||
size_t decodeToBinSize(EncodeType encodeType, const char *source);
|
size_t decodeToBinSize(EncodeType type, const char *source);
|
||||||
|
|
||||||
// Check that the encoded string is valid
|
// Check that the encoded string is valid
|
||||||
bool decodeToBinValid(EncodeType encodeType, const char *source);
|
bool decodeToBinValid(EncodeType type, const char *source);
|
||||||
|
|
||||||
// Validate the encoded string
|
// Validate the encoded string
|
||||||
void decodeToBinValidate(EncodeType encodeType, const char *source);
|
void decodeToBinValidate(EncodeType type, const char *source);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -40,9 +40,6 @@ testRun(void)
|
|||||||
TEST_RESULT_Z(destinationEncode, "c3RyaW5nX3RvX2VuY29kZQ0KAA==", "encode full string with \\r\\n and null");
|
TEST_RESULT_Z(destinationEncode, "c3RyaW5nX3RvX2VuY29kZQ0KAA==", "encode full string with \\r\\n and null");
|
||||||
TEST_RESULT_UINT(encodeToStrSize(encodeBase64, strlen((char *)encode) + 1), strlen(destinationEncode), "check size");
|
TEST_RESULT_UINT(encodeToStrSize(encodeBase64, strlen((char *)encode) + 1), strlen(destinationEncode), "check size");
|
||||||
|
|
||||||
TEST_ERROR(encodeToStr(999, encode, strlen((char *)encode), destinationEncode), AssertError, "invalid encode type 999");
|
|
||||||
TEST_ERROR(encodeToStrSize(999, strlen((char *)encode)), AssertError, "invalid encode type 999");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
unsigned char destinationDecode[256];
|
unsigned char destinationDecode[256];
|
||||||
|
|
||||||
@@ -88,9 +85,8 @@ testRun(void)
|
|||||||
TEST_RESULT_INT(destinationDecode[1], 0xFF, "check for overrun");
|
TEST_RESULT_INT(destinationDecode[1], 0xFF, "check for overrun");
|
||||||
TEST_RESULT_UINT(decodeToBinSize(encodeBase64, decode), 1, "check size");
|
TEST_RESULT_UINT(decodeToBinSize(encodeBase64, decode), 1, "check size");
|
||||||
|
|
||||||
TEST_ERROR(decodeToBin(9999, decode, destinationDecode), AssertError, "invalid encode type 9999");
|
TEST_ERROR(
|
||||||
TEST_ERROR(decodeToBinSize(9999, decode), AssertError, "invalid encode type 9999");
|
decodeToBin(encodeBase64, "cc$=", destinationDecode), FormatError, "base64 invalid character found at position 2");
|
||||||
TEST_ERROR(decodeToBin(encodeBase64, "cc$=", destinationDecode), FormatError, "base64 invalid character found at position 2");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_ERROR(decodeToBinValidate(encodeBase64, "c3"), FormatError, "base64 size 2 is not evenly divisible by 4");
|
TEST_ERROR(decodeToBinValidate(encodeBase64, "c3"), FormatError, "base64 size 2 is not evenly divisible by 4");
|
||||||
@@ -99,13 +95,9 @@ testRun(void)
|
|||||||
TEST_ERROR(
|
TEST_ERROR(
|
||||||
decodeToBinValidate(encodeBase64, "cc=c"), FormatError, "base64 last character must be '=' if second to last is");
|
decodeToBinValidate(encodeBase64, "cc=c"), FormatError, "base64 last character must be '=' if second to last is");
|
||||||
|
|
||||||
TEST_ERROR(decodeToBinValidate(9999, "cc=c"), AssertError, "invalid encode type 9999");
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_RESULT_BOOL(decodeToBinValid(encodeBase64, "CCCCCCCCCCC"), false, "base64 string not valid");
|
TEST_RESULT_BOOL(decodeToBinValid(encodeBase64, "CCCCCCCCCCC"), false, "base64 string not valid");
|
||||||
TEST_RESULT_BOOL(decodeToBinValid(encodeBase64, "CCCCCCCCCCCC"), true, "base64 string valid");
|
TEST_RESULT_BOOL(decodeToBinValid(encodeBase64, "CCCCCCCCCCCC"), true, "base64 string valid");
|
||||||
|
|
||||||
TEST_ERROR(decodeToBinValid(9999, "CCCCCCCCCCCC"), AssertError, "invalid encode type 9999");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FUNCTION_HARNESS_RESULT_VOID();
|
FUNCTION_HARNESS_RESULT_VOID();
|
||||||
|
|||||||
Reference in New Issue
Block a user