From 3a7a8074b080f8b7d6620017c39295846f5f171c Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Tue, 11 Dec 2018 16:13:58 -0500 Subject: [PATCH] rgw: parse_copy_location defers url-decode don't url-decode until after we search for the ?, or we'll truncate object names that contain a url-encoded ? Fixes: http://tracker.ceph.com/issues/27217 Signed-off-by: Casey Bodley (cherry picked from commit 804bb853f1c7b5ce546c100d61c6fc526838c134) --- src/rgw/rgw_op.cc | 10 ++++------ src/rgw/rgw_rest_s3.cc | 2 +- src/rgw/rgw_rest_swift.cc | 6 ++---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index cb795825978ee..60b86f7c1d756 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -4367,6 +4367,7 @@ bool RGWCopyObj::parse_copy_location(const boost::string_view& url_src, boost::string_view name_str; boost::string_view params_str; + // search for ? before url-decoding so we don't accidentally match %3F size_t pos = url_src.find('?'); if (pos == string::npos) { name_str = url_src; @@ -4380,14 +4381,11 @@ bool RGWCopyObj::parse_copy_location(const boost::string_view& url_src, dec_src.remove_prefix(1); pos = dec_src.find('/'); - if (pos ==string::npos) + if (pos == string::npos) return false; - boost::string_view bn_view{dec_src.substr(0, pos)}; - bucket_name = std::string{bn_view.data(), bn_view.size()}; - - boost::string_view kn_view{dec_src.substr(pos + 1)}; - key.name = std::string{kn_view.data(), kn_view.size()}; + bucket_name = url_decode(dec_src.substr(0, pos)); + key.name = url_decode(dec_src.substr(pos + 1)); if (key.name.empty()) { return false; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index f0de32e6a0c9e..1fdfeccb28883 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -3339,7 +3339,7 @@ int RGWHandler_REST_S3::init(RGWRados *store, struct req_state *s, (! s->info.env->get("HTTP_X_AMZ_COPY_SOURCE_RANGE")) && (! s->info.args.exists("uploadId"))) { - ret = RGWCopyObj::parse_copy_location(url_decode(copy_source), + ret = RGWCopyObj::parse_copy_location(copy_source, s->init_state.src_bucket, s->src_object); if (!ret) { diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 35e192c150ed3..c47c50e50a843 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -2908,8 +2908,7 @@ int RGWHandler_REST_SWIFT::init(RGWRados* store, struct req_state* s, s->dialect = "swift"; - std::string copy_source = - url_decode(s->info.env->get("HTTP_X_COPY_FROM", "")); + std::string copy_source = s->info.env->get("HTTP_X_COPY_FROM", ""); if (! copy_source.empty()) { bool result = RGWCopyObj::parse_copy_location(copy_source, t->src_bucket, s->src_object); @@ -2918,8 +2917,7 @@ int RGWHandler_REST_SWIFT::init(RGWRados* store, struct req_state* s, } if (s->op == OP_COPY) { - std::string req_dest = - url_decode(s->info.env->get("HTTP_DESTINATION", "")); + std::string req_dest = s->info.env->get("HTTP_DESTINATION", ""); if (req_dest.empty()) return -ERR_BAD_URL; -- 2.39.5