Merge pull request #22721 from linuxbox2/wip-rgw-23099

rgw: escape markers in RGWOp_Metadata_List::execute

Reviewed-by: Yehuda Sadeh <yehuda@redhat.com>
This commit is contained in:
Yuri Weinstein 2018-07-06 11:46:13 -07:00 committed by GitHub
commit 6e156812d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 52 deletions

View File

@ -1740,56 +1740,11 @@ bool RGWUserCaps::is_valid_cap_type(const string& tp)
return false;
}
static ssize_t unescape_str(const string& s, ssize_t ofs, char esc_char, char special_char, string *dest)
{
const char *src = s.c_str();
char dest_buf[s.size() + 1];
char *destp = dest_buf;
bool esc = false;
dest_buf[0] = '\0';
for (size_t i = ofs; i < s.size(); i++) {
char c = src[i];
if (!esc && c == esc_char) {
esc = true;
continue;
}
if (!esc && c == special_char) {
*destp = '\0';
*dest = dest_buf;
return (ssize_t)i + 1;
}
*destp++ = c;
esc = false;
}
*destp = '\0';
*dest = dest_buf;
return string::npos;
}
static void escape_str(const string& s, char esc_char, char special_char, string *dest)
{
const char *src = s.c_str();
char dest_buf[s.size() * 2 + 1];
char *destp = dest_buf;
for (size_t i = 0; i < s.size(); i++) {
char c = src[i];
if (c == esc_char || c == special_char) {
*destp++ = esc_char;
}
*destp++ = c;
}
*destp++ = '\0';
*dest = dest_buf;
}
void rgw_pool::from_str(const string& s)
{
size_t pos = unescape_str(s, 0, '\\', ':', &name);
size_t pos = rgw_unescape_str(s, 0, '\\', ':', &name);
if (pos != string::npos) {
pos = unescape_str(s, pos, '\\', ':', &ns);
pos = rgw_unescape_str(s, pos, '\\', ':', &ns);
/* ignore return; if pos != string::npos it means that we had a colon
* in the middle of ns that wasn't escaped, we're going to stop there
*/
@ -1799,12 +1754,12 @@ void rgw_pool::from_str(const string& s)
string rgw_pool::to_str() const
{
string esc_name;
escape_str(name, '\\', ':', &esc_name);
rgw_escape_str(name, '\\', ':', &esc_name);
if (ns.empty()) {
return esc_name;
}
string esc_ns;
escape_str(ns, '\\', ':', &esc_ns);
rgw_escape_str(ns, '\\', ':', &esc_ns);
return esc_name + ":" + esc_ns;
}

View File

@ -2400,4 +2400,52 @@ extern string lowercase_dash_http_attr(const string& orig);
void rgw_setup_saved_curl_handles();
void rgw_release_all_curl_handles();
static inline void rgw_escape_str(const string& s, char esc_char,
char special_char, string *dest)
{
const char *src = s.c_str();
char dest_buf[s.size() * 2 + 1];
char *destp = dest_buf;
for (size_t i = 0; i < s.size(); i++) {
char c = src[i];
if (c == esc_char || c == special_char) {
*destp++ = esc_char;
}
*destp++ = c;
}
*destp++ = '\0';
*dest = dest_buf;
}
static inline ssize_t rgw_unescape_str(const string& s, ssize_t ofs,
char esc_char, char special_char,
string *dest)
{
const char *src = s.c_str();
char dest_buf[s.size() + 1];
char *destp = dest_buf;
bool esc = false;
dest_buf[0] = '\0';
for (size_t i = ofs; i < s.size(); i++) {
char c = src[i];
if (!esc && c == esc_char) {
esc = true;
continue;
}
if (!esc && c == special_char) {
*destp = '\0';
*dest = dest_buf;
return (ssize_t)i + 1;
}
*destp++ = c;
esc = false;
}
*destp = '\0';
*dest = dest_buf;
return string::npos;
}
#endif

View File

@ -20,6 +20,7 @@
#include "rgw_client_io.h"
#include "common/errno.h"
#include "common/strtol.h"
#include "rgw/rgw_b64.h"
#include "include/assert.h"
#define dout_context g_ceph_context
@ -69,9 +70,25 @@ void RGWOp_Metadata_Get_Myself::execute() {
}
void RGWOp_Metadata_List::execute() {
string marker = s->info.args.get("marker");
string marker;
ldout(s->cct, 16) << __func__
<< " raw marker " << s->info.args.get("marker")
<< dendl;
try {
marker = s->info.args.get("marker");
if (!marker.empty()) {
marker = rgw::from_base64(marker);
}
ldout(s->cct, 16) << __func__
<< " marker " << marker << dendl;
} catch (...) {
marker = std::string("");
}
bool max_entries_specified;
string max_entries_str = s->info.args.get("max-entries", &max_entries_specified);
string max_entries_str =
s->info.args.get("max-entries", &max_entries_specified);
bool extended_response = (max_entries_specified); /* for backward compatibility, if max-entries is not specified
we will send the old response format */
@ -94,6 +111,12 @@ void RGWOp_Metadata_List::execute() {
void *handle;
int max = 1000;
/* example markers:
marker = "3:b55a9110:root::bu_9:head";
marker = "3:b9a8b2a6:root::sorry_janefonda_890:head";
marker = "3:bf885d8f:root::sorry_janefonda_665:head";
*/
http_ret = store->meta_mgr->list_keys_init(metadata_key, marker, &handle);
if (http_ret < 0) {
dout(5) << "ERROR: can't get key: " << cpp_strerror(http_ret) << dendl;
@ -134,7 +157,9 @@ void RGWOp_Metadata_List::execute() {
encode_json("truncated", truncated, s->formatter);
encode_json("count", count, s->formatter);
if (truncated) {
encode_json("marker", store->meta_mgr->get_marker(handle), s->formatter);
string esc_marker =
rgw::to_base64(store->meta_mgr->get_marker(handle));
encode_json("marker", esc_marker, s->formatter);
}
s->formatter->close_section();
}