Revert "change implementation of Exiv2::base64encode() to adopt implementation from same URL as base64decode()."
This reverts commit b596f311f4.
This commit is contained in:
committed by
Luis Díaz Más
parent
b596f311f4
commit
b9164d9f8b
+114
-107
@@ -139,117 +139,124 @@ namespace Exiv2 {
|
||||
delete [] decodeStr;
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
|
||||
static const std::string base64_chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
static inline bool is_base64(unsigned char c) {
|
||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||
}
|
||||
|
||||
static std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
|
||||
std::string ret;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
unsigned char char_array_3[3];
|
||||
unsigned char char_array_4[4];
|
||||
|
||||
while (in_len--) {
|
||||
char_array_3[i++] = *(bytes_to_encode++);
|
||||
if (i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for(i = 0; (i <4) ; i++)
|
||||
ret += base64_chars[char_array_4[i]];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for(j = i; j < 3; j++)
|
||||
char_array_3[j] = '\0';
|
||||
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for (j = 0; (j < i + 1); j++)
|
||||
ret += base64_chars[char_array_4[j]];
|
||||
|
||||
while((i++ < 3))
|
||||
ret += '=';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::string base64_decode(std::string const& encoded_string) {
|
||||
int in_len = encoded_string.size();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int in_ = 0;
|
||||
unsigned char char_array_4[4], char_array_3[3];
|
||||
std::string ret;
|
||||
|
||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
if (i ==4) {
|
||||
for (i = 0; i <4; i++)
|
||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (i = 0; (i < 3); i++)
|
||||
ret += char_array_3[i];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j <4; j++)
|
||||
char_array_4[j] = 0;
|
||||
|
||||
for (j = 0; j <4; j++)
|
||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int base64encode(const void* data_buf, size_t dataLength, char* result, size_t resultSize) {
|
||||
int rc = 0 ; // failed
|
||||
std::string encoded = base64_encode((unsigned char const*)data_buf, (unsigned int) dataLength) ;
|
||||
if (encoded.size() < resultSize ) {
|
||||
memcpy(result,encoded.c_str(),encoded.size());
|
||||
rc = 1 ; // indicate success
|
||||
const char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
const uint8_t* data = (const uint8_t*)data_buf;
|
||||
size_t resultIndex = 0;
|
||||
size_t x;
|
||||
uint32_t n = 0;
|
||||
size_t padCount = dataLength % 3;
|
||||
uint8_t n0, n1, n2, n3;
|
||||
|
||||
/* increment over the length of the string, three characters at a time */
|
||||
for (x = 0; x < dataLength; x += 3)
|
||||
{
|
||||
/* these three 8-bit (ASCII) characters become one 24-bit number */
|
||||
n = data[x] << 16;
|
||||
|
||||
if((x+1) < dataLength)
|
||||
n += data[x+1] << 8;
|
||||
|
||||
if((x+2) < dataLength)
|
||||
n += data[x+2];
|
||||
|
||||
/* this 24-bit number gets separated into four 6-bit numbers */
|
||||
n0 = (uint8_t)(n >> 18) & 63;
|
||||
n1 = (uint8_t)(n >> 12) & 63;
|
||||
n2 = (uint8_t)(n >> 6) & 63;
|
||||
n3 = (uint8_t)n & 63;
|
||||
|
||||
/*
|
||||
* if we have one byte available, then its encoding is spread
|
||||
* out over two characters
|
||||
*/
|
||||
if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */
|
||||
result[resultIndex++] = base64chars[n0];
|
||||
if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */
|
||||
result[resultIndex++] = base64chars[n1];
|
||||
|
||||
/*
|
||||
* if we have only two bytes available, then their encoding is
|
||||
* spread out over three chars
|
||||
*/
|
||||
if((x+1) < dataLength)
|
||||
{
|
||||
if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */
|
||||
result[resultIndex++] = base64chars[n2];
|
||||
}
|
||||
|
||||
/*
|
||||
* if we have all three bytes available, then their encoding is spread
|
||||
* out over four characters
|
||||
*/
|
||||
if((x+2) < dataLength)
|
||||
{
|
||||
if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */
|
||||
result[resultIndex++] = base64chars[n3];
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* create and add padding that is required if we did not have a multiple of 3
|
||||
* number of characters available
|
||||
*/
|
||||
if (padCount > 0)
|
||||
{
|
||||
for (; padCount < 3; padCount++)
|
||||
{
|
||||
if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */
|
||||
result[resultIndex++] = '=';
|
||||
}
|
||||
}
|
||||
if(resultIndex >= resultSize) return 0; /* indicate failure: buffer too small */
|
||||
result[resultIndex] = 0;
|
||||
return 1; /* indicate success */
|
||||
} // base64encode
|
||||
|
||||
long base64decode(const char *in, char *out, size_t out_size)
|
||||
{
|
||||
std::string in_string(in);
|
||||
std::string out_string = base64_decode(in_string);
|
||||
long result = (long) out_string.size();
|
||||
if ( (long) out_size > result ) {
|
||||
memcpy(out,out_string.c_str(),result);
|
||||
out[result] = 0;
|
||||
} else result = -1 ;
|
||||
return result;
|
||||
}
|
||||
long base64decode(const char *in, char *out, size_t out_size) {
|
||||
static const char decode[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW"
|
||||
"$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
|
||||
long len;
|
||||
long i;
|
||||
long done = 0;
|
||||
unsigned char v;
|
||||
unsigned char quad[4];
|
||||
|
||||
while (*in) {
|
||||
len = 0;
|
||||
for (i = 0; i < 4 && *in; i++) {
|
||||
v = 0;
|
||||
while (*in && !v) {
|
||||
v = *in++;
|
||||
v = (v < 43 || v > 122) ? 0 : decode[v - 43];
|
||||
if (v)
|
||||
v = (v == '$') ? 0 : v - 61;
|
||||
if (*in) {
|
||||
len++;
|
||||
if (v)
|
||||
quad[i] = v - 1;
|
||||
} else
|
||||
quad[i] = 0;
|
||||
}
|
||||
}
|
||||
if (!len)
|
||||
continue;
|
||||
if (out_size < (size_t) (done + len - 1))
|
||||
/* out buffer is too small */
|
||||
return -1;
|
||||
if (len >= 2)
|
||||
*out++ = quad[0] << 2 | quad[1] >> 4;
|
||||
if (len >= 3)
|
||||
*out++ = quad[1] << 4 | quad[2] >> 2;
|
||||
if (len >= 4)
|
||||
*out++ = ((quad[2] << 6) & 0xc0) | quad[3];
|
||||
done += len - 1;
|
||||
}
|
||||
if ((size_t)(done + 1) >= out_size)
|
||||
return -1;
|
||||
*out++ = '\0';
|
||||
return done;
|
||||
} // base64decode
|
||||
|
||||
Protocol fileProtocol(const std::string& path) {
|
||||
Protocol result = pFile ;
|
||||
|
||||
Reference in New Issue
Block a user