diff options
author | Ondřej Surý <ondrej@sury.org> | 2013-06-28 12:59:40 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2013-06-28 13:12:06 +0200 |
commit | a660d5181d79af97a439169b8d5e7dc2dc36e92f (patch) | |
tree | 6c33f9a8419411759298ec06834d20bce31a5280 /src/common/base64.c | |
parent | 74949f934e2330c717f2c2f6b3fc17b7bde472b6 (diff) | |
download | knot-a660d5181d79af97a439169b8d5e7dc2dc36e92f.tar.gz |
New upstream version 1.3.0~rc3
Diffstat (limited to 'src/common/base64.c')
-rw-r--r-- | src/common/base64.c | 94 |
1 files changed, 56 insertions, 38 deletions
diff --git a/src/common/base64.c b/src/common/base64.c index a153a70..3deee97 100644 --- a/src/common/base64.c +++ b/src/common/base64.c @@ -14,7 +14,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <config.h> #include "base64.h" +#include "errcode.h" #include <stdlib.h> // malloc #include <stdint.h> // uint8_t @@ -81,9 +83,9 @@ const uint8_t base64_dec[256] = { }; int32_t base64_encode(const uint8_t *in, - const uint32_t in_len, - uint8_t *out, - const uint32_t out_len) + const uint32_t in_len, + uint8_t *out, + const uint32_t out_len) { uint8_t rest_len = in_len % 3; const uint8_t *data = in; @@ -92,9 +94,11 @@ int32_t base64_encode(const uint8_t *in, uint8_t num; // Checking inputs. - if (in == NULL || out == NULL || in_len > MAX_BIN_DATA_LEN || - out_len < ((in_len + 2) / 3) * 4) { - return -1; + if (in == NULL || out == NULL) { + return KNOT_EINVAL; + } + if (in_len > MAX_BIN_DATA_LEN || out_len < ((in_len + 2) / 3) * 4) { + return KNOT_ERANGE; } // Encoding loop takes 3 bytes and creates 4 characters. @@ -121,7 +125,7 @@ int32_t base64_encode(const uint8_t *in, // Processing of padding, if any. switch (rest_len) { // Input data has 2-byte last block => 1-char padding. - case 2: + case 2: // Computing 1. Base64 character. num = *data >> 2; *text++ = base64_enc[num]; @@ -138,9 +142,9 @@ int32_t base64_encode(const uint8_t *in, // 1 padding character. *text++ = base64_pad; - break; + break; // Input data has 1-byte last block => 2-char padding. - case 1: + case 1: // Computing 1. Base64 character. num = *data >> 2; *text++ = base64_enc[num]; @@ -153,38 +157,43 @@ int32_t base64_encode(const uint8_t *in, *text++ = base64_pad; *text++ = base64_pad; - break; + break; } return (text - out); } int32_t base64_encode_alloc(const uint8_t *in, - const uint32_t in_len, - uint8_t **out) + const uint32_t in_len, + uint8_t **out) { - uint32_t out_len = ((in_len + 2) / 3) * 4; - - // Checking inputs. + // Check input (output is longer). if (in_len > MAX_BIN_DATA_LEN) { - return -1; + return KNOT_ERANGE; } - // Allocating output buffer. - *out = malloc(out_len); + // Compute output buffer length. + uint32_t out_len = ((in_len + 2) / 3) * 4; + // Allocate output buffer. + *out = malloc(out_len); if (*out == NULL) { - return -1; + return KNOT_ENOMEM; } - // Encoding data. - return base64_encode(in, in_len, *out, out_len); + // Encode data. + int32_t ret = base64_encode(in, in_len, *out, out_len); + if (ret < 0) { + free(*out); + } + + return ret; } int32_t base64_decode(const uint8_t *in, - const uint32_t in_len, - uint8_t *out, - const uint32_t out_len) + const uint32_t in_len, + uint8_t *out, + const uint32_t out_len) { const uint8_t *data = in; const uint8_t *stop = in + in_len; @@ -193,9 +202,14 @@ int32_t base64_decode(const uint8_t *in, uint8_t c1, c2, c3, c4; // Checking inputs. - if (in == NULL || out == NULL || (in_len % 4) != 0 || - in_len > INT32_MAX || out_len < ((in_len + 3) / 4) * 3) { - return -1; + if (in == NULL || out == NULL) { + return KNOT_EINVAL; + } + if (in_len > INT32_MAX || out_len < ((in_len + 3) / 4) * 3) { + return KNOT_ERANGE; + } + if ((in_len % 4) != 0) { + return KNOT_BASE64_ESIZE; } // Decoding loop takes 4 characters and creates 3 bytes. @@ -211,7 +225,7 @@ int32_t base64_decode(const uint8_t *in, if (c4 == PD) { pad_len = 1; } else { - return -2; + return KNOT_BASE64_ECHAR; } } @@ -220,13 +234,13 @@ int32_t base64_decode(const uint8_t *in, if (c3 == PD) { pad_len = 2; } else { - return -2; + return KNOT_BASE64_ECHAR; } } // 1. and 2. chars must not be padding. if (c2 >= PD || c1 >= PD) { - return -2; + return KNOT_BASE64_ECHAR; } // Computing of output data based on padding length. @@ -253,19 +267,23 @@ int32_t base64_decode(const uint8_t *in, } int32_t base64_decode_alloc(const uint8_t *in, - const uint32_t in_len, - uint8_t **out) + const uint32_t in_len, + uint8_t **out) { + // Compute output buffer length. uint32_t out_len = ((in_len + 3) / 4) * 3; + // Allocate output buffer. *out = malloc(out_len); - - // Allocating output buffer. if (*out == NULL) { - return -1; + return KNOT_ENOMEM; } - // Decoding data. - return base64_decode(in, in_len, *out, out_len); -} + // Decode data. + int32_t ret = base64_decode(in, in_len, *out, out_len); + if (ret < 0) { + free(*out); + } + return ret; +} |