fix: correct Base64 encoding for 2-byte remainder
The original code used separate shifts for each byte instead of combining them into a single 24-bit value first, producing wrong output for credentials with lengths that leave 2-byte remainders (e.g. 'user:pass').
This commit is contained in:
@@ -58,19 +58,18 @@ namespace {
|
|||||||
if (remaining > 0) {
|
if (remaining > 0) {
|
||||||
const std::uint32_t octet = (static_cast<std::uint32_t>(
|
const std::uint32_t octet = (static_cast<std::uint32_t>(
|
||||||
static_cast<unsigned char>(input[i]))
|
static_cast<unsigned char>(input[i]))
|
||||||
<< 16);
|
<< 16)
|
||||||
if (remaining == 2) {
|
| (remaining == 2 ? (static_cast<std::uint32_t>(
|
||||||
const std::uint32_t second = static_cast<std::uint32_t>(
|
|
||||||
static_cast<unsigned char>(input[i + 1]))
|
static_cast<unsigned char>(input[i + 1]))
|
||||||
<< 8;
|
<< 8)
|
||||||
output.push_back(table[((octet | second) >> 18) & 0x3f]);
|
: 0);
|
||||||
output.push_back(table[((octet | second) >> 12) & 0x3f]);
|
|
||||||
output.push_back(table[((octet | second) >> 6) & 0x3f]);
|
|
||||||
output.push_back('=');
|
|
||||||
} else {
|
|
||||||
output.push_back(table[(octet >> 18) & 0x3f]);
|
output.push_back(table[(octet >> 18) & 0x3f]);
|
||||||
output.push_back(table[(octet >> 12) & 0x3f]);
|
output.push_back(table[(octet >> 12) & 0x3f]);
|
||||||
|
if (remaining == 2) {
|
||||||
|
output.push_back(table[(octet >> 6) & 0x3f]);
|
||||||
|
}
|
||||||
output.push_back('=');
|
output.push_back('=');
|
||||||
|
if (remaining == 1) {
|
||||||
output.push_back('=');
|
output.push_back('=');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,6 +103,7 @@ void CalDAVSync::discover() {
|
|||||||
{"Depth", "0"},
|
{"Depth", "0"},
|
||||||
{"Content-Type", "application/xml; charset=utf-8"},
|
{"Content-Type", "application/xml; charset=utf-8"},
|
||||||
{"Authorization", "Basic " + encode_basic_auth()},
|
{"Authorization", "Basic " + encode_basic_auth()},
|
||||||
|
{"Overwrite", "F"},
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string principal_response = send_request(
|
const std::string principal_response = send_request(
|
||||||
@@ -177,6 +177,7 @@ std::vector<CalDAVCalendar> CalDAVSync::list_calendars() {
|
|||||||
{"Depth", "1"},
|
{"Depth", "1"},
|
||||||
{"Content-Type", "application/xml; charset=utf-8"},
|
{"Content-Type", "application/xml; charset=utf-8"},
|
||||||
{"Authorization", "Basic " + encode_basic_auth()},
|
{"Authorization", "Basic " + encode_basic_auth()},
|
||||||
|
{"Overwrite", "F"},
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::string response = send_request(
|
const std::string response = send_request(
|
||||||
@@ -390,13 +391,15 @@ std::string CalDAVSync::send_request(const int method, const std::string& url,
|
|||||||
|
|
||||||
const auto response = transport_.send(request);
|
const auto response = transport_.send(request);
|
||||||
if (response.status == 401) {
|
if (response.status == 401) {
|
||||||
throw std::runtime_error("CalDAV: authentication failed");
|
throw std::runtime_error("CalDAV: authentication failed (status 401) from " + url
|
||||||
|
+ "\nCheck that --server points to the CalDAV root (e.g. "
|
||||||
|
"https://cloud.example.com/remote.php/dav) and that the username/password are correct.");
|
||||||
}
|
}
|
||||||
if (response.status == 403) {
|
if (response.status == 403) {
|
||||||
throw std::runtime_error("CalDAV: forbidden");
|
throw std::runtime_error("CalDAV: forbidden from " + url);
|
||||||
}
|
}
|
||||||
if (response.status == 404) {
|
if (response.status == 404) {
|
||||||
throw std::runtime_error("CalDAV: resource not found: " + url);
|
throw std::runtime_error("CalDAV: resource not found from " + url);
|
||||||
}
|
}
|
||||||
if (response.status != 200 && response.status != 207) {
|
if (response.status != 200 && response.status != 207) {
|
||||||
throw std::runtime_error("CalDAV: unexpected status " + std::to_string(response.status)
|
throw std::runtime_error("CalDAV: unexpected status " + std::to_string(response.status)
|
||||||
|
|||||||
Reference in New Issue
Block a user