mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-01-18 04:58:51 +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:
parent
abcbe0f9c1
commit
edab2a0b89
@ -11,10 +11,10 @@ Binary to String Encode/Decode
|
||||
#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) \
|
||||
THROW_FMT(AssertError, "invalid encode type %u", encodeType);
|
||||
#define ASSERT_ENCODE_TYPE_VALID(type) \
|
||||
ASSERT(type <= encodeBase64);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Base64 encoding/decoding
|
||||
@ -228,85 +228,101 @@ decodeToBinSizeBase64(const char *source)
|
||||
Generic encoding/decoding
|
||||
***********************************************************************************************************************************/
|
||||
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_PARAM(ENUM, encodeType);
|
||||
FUNCTION_TEST_PARAM(ENUM, type);
|
||||
FUNCTION_TEST_PARAM_P(UCHARDATA, source);
|
||||
FUNCTION_TEST_PARAM(SIZE, sourceSize);
|
||||
FUNCTION_TEST_PARAM_P(CHARDATA, destination);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
if (encodeType == encodeBase64)
|
||||
encodeToStrBase64(source, sourceSize, destination);
|
||||
else
|
||||
ENCODE_TYPE_INVALID_ERROR(encodeType);
|
||||
ASSERT_ENCODE_TYPE_VALID(type);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case encodeBase64:
|
||||
encodeToStrBase64(source, sourceSize, destination);
|
||||
break;
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
size_t
|
||||
encodeToStrSize(EncodeType encodeType, size_t sourceSize)
|
||||
encodeToStrSize(EncodeType type, size_t sourceSize)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(ENUM, encodeType);
|
||||
FUNCTION_TEST_PARAM(ENUM, type);
|
||||
FUNCTION_TEST_PARAM(SIZE, sourceSize);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
size_t destinationSize = 0;
|
||||
ASSERT_ENCODE_TYPE_VALID(type);
|
||||
|
||||
if (encodeType == encodeBase64)
|
||||
destinationSize = encodeToStrSizeBase64(sourceSize);
|
||||
else
|
||||
ENCODE_TYPE_INVALID_ERROR(encodeType);
|
||||
size_t destinationSize = SIZE_MAX;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case encodeBase64:
|
||||
destinationSize = encodeToStrSizeBase64(sourceSize);
|
||||
break;
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(destinationSize);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
decodeToBin(EncodeType encodeType, const char *source, unsigned char *destination)
|
||||
decodeToBin(EncodeType type, const char *source, unsigned char *destination)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(ENUM, encodeType);
|
||||
FUNCTION_TEST_PARAM(ENUM, type);
|
||||
FUNCTION_TEST_PARAM(STRINGZ, source);
|
||||
FUNCTION_TEST_PARAM_P(UCHARDATA, destination);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
if (encodeType == encodeBase64)
|
||||
decodeToBinBase64(source, destination);
|
||||
else
|
||||
ENCODE_TYPE_INVALID_ERROR(encodeType);
|
||||
ASSERT_ENCODE_TYPE_VALID(type);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case encodeBase64:
|
||||
decodeToBinBase64(source, destination);
|
||||
break;
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
size_t
|
||||
decodeToBinSize(EncodeType encodeType, const char *source)
|
||||
decodeToBinSize(EncodeType type, const char *source)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(ENUM, encodeType);
|
||||
FUNCTION_TEST_PARAM(ENUM, type);
|
||||
FUNCTION_TEST_PARAM(STRINGZ, source);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
size_t destinationSize = 0;
|
||||
ASSERT_ENCODE_TYPE_VALID(type);
|
||||
|
||||
if (encodeType == encodeBase64)
|
||||
destinationSize = decodeToBinSizeBase64(source);
|
||||
else
|
||||
ENCODE_TYPE_INVALID_ERROR(encodeType);
|
||||
size_t destinationSize = SIZE_MAX;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case encodeBase64:
|
||||
destinationSize = decodeToBinSizeBase64(source);
|
||||
break;
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(destinationSize);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
bool
|
||||
decodeToBinValid(EncodeType encodeType, const char *source)
|
||||
decodeToBinValid(EncodeType type, const char *source)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(ENUM, encodeType);
|
||||
FUNCTION_TEST_PARAM(ENUM, type);
|
||||
FUNCTION_TEST_PARAM(STRINGZ, source);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
@ -314,7 +330,7 @@ decodeToBinValid(EncodeType encodeType, const char *source)
|
||||
|
||||
TRY_BEGIN()
|
||||
{
|
||||
decodeToBinValidate(encodeType, source);
|
||||
decodeToBinValidate(type, source);
|
||||
}
|
||||
CATCH(FormatError)
|
||||
{
|
||||
@ -327,17 +343,21 @@ decodeToBinValid(EncodeType encodeType, const char *source)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
decodeToBinValidate(EncodeType encodeType, const char *source)
|
||||
decodeToBinValidate(EncodeType type, const char *source)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(ENUM, encodeType);
|
||||
FUNCTION_TEST_PARAM(ENUM, type);
|
||||
FUNCTION_TEST_PARAM(STRINGZ, source);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
if (encodeType == encodeBase64)
|
||||
decodeToBinValidateBase64(source);
|
||||
else
|
||||
ENCODE_TYPE_INVALID_ERROR(encodeType);
|
||||
ASSERT_ENCODE_TYPE_VALID(type);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case encodeBase64:
|
||||
decodeToBinValidateBase64(source);
|
||||
break;
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
@ -20,21 +20,21 @@ typedef enum
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
// 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_t encodeToStrSize(EncodeType encodeType, size_t sourceSize);
|
||||
size_t encodeToStrSize(EncodeType type, size_t sourceSize);
|
||||
|
||||
// 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_t decodeToBinSize(EncodeType encodeType, const char *source);
|
||||
size_t decodeToBinSize(EncodeType type, const char *source);
|
||||
|
||||
// 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
|
||||
void decodeToBinValidate(EncodeType encodeType, const char *source);
|
||||
void decodeToBinValidate(EncodeType type, const char *source);
|
||||
|
||||
#endif
|
||||
|
@ -40,9 +40,6 @@ testRun(void)
|
||||
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_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];
|
||||
|
||||
@ -88,9 +85,8 @@ testRun(void)
|
||||
TEST_RESULT_INT(destinationDecode[1], 0xFF, "check for overrun");
|
||||
TEST_RESULT_UINT(decodeToBinSize(encodeBase64, decode), 1, "check size");
|
||||
|
||||
TEST_ERROR(decodeToBin(9999, decode, destinationDecode), AssertError, "invalid encode type 9999");
|
||||
TEST_ERROR(decodeToBinSize(9999, decode), AssertError, "invalid encode type 9999");
|
||||
TEST_ERROR(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");
|
||||
@ -99,13 +95,9 @@ testRun(void)
|
||||
TEST_ERROR(
|
||||
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, "CCCCCCCCCCCC"), true, "base64 string valid");
|
||||
|
||||
TEST_ERROR(decodeToBinValid(9999, "CCCCCCCCCCCC"), AssertError, "invalid encode type 9999");
|
||||
}
|
||||
|
||||
FUNCTION_HARNESS_RESULT_VOID();
|
||||
|
Loading…
x
Reference in New Issue
Block a user