|
|
|
@ -212,51 +212,70 @@ namespace Exiv2 {
|
|
|
|
|
result[resultIndex] = 0;
|
|
|
|
|
return 1; /* indicate success */
|
|
|
|
|
} // base64encode
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
// 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_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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Protocol fileProtocol(const std::string& path) {
|
|
|
|
|
Protocol result = pFile ;
|
|
|
|
|