return ret;
}
-static int read_all_chunked_input(req_state *s, char **pdata, int *plen)
+static int read_all_chunked_input(req_state *s, char **pdata, int *plen, int max_read)
{
#define READ_CHUNK 4096
#define MAX_READ_CHUNK (128 * 1024)
if (need_to_read < MAX_READ_CHUNK)
need_to_read *= 2;
+ if (total > max_read) {
+ free(data);
+ return -ERANGE;
+ }
total += need_to_read;
void *p = realloc(data, total + 1);
return 0;
}
-int RGWCompleteMultipart_ObjStore::get_params()
+int rgw_rest_read_all_input(struct req_state *s, char **pdata, int *plen, int max_len)
{
- upload_id = s->args.get("uploadId");
-
- if (upload_id.empty()) {
- ret = -ENOTSUP;
- return ret;
- }
size_t cl = 0;
+ int len = 0;
+ char *data = NULL;
if (s->length)
cl = atoll(s->length);
if (cl) {
+ if (cl > (size_t)max_len) {
+ return -ERANGE;
+ }
data = (char *)malloc(cl + 1);
if (!data) {
- ret = -ENOMEM;
- return ret;
+ return -ENOMEM;
}
- ret = s->cio->read(data, cl, &len);
+ int ret = s->cio->read(data, cl, &len);
if (ret < 0)
return ret;
data[len] = '\0';
- } else {
+ } else if (!s->length) {
const char *encoding = s->env->get("HTTP_TRANSFER_ENCODING");
if (!encoding || strcmp(encoding, "chunked") != 0)
return -ERR_LENGTH_REQUIRED;
- ret = read_all_chunked_input(s, &data, &len);
+ int ret = read_all_chunked_input(s, &data, &len, max_len);
if (ret < 0)
return ret;
}
- return ret;
+ *plen = len;
+ *pdata = data;
+
+ return 0;
+}
+
+
+int RGWCompleteMultipart_ObjStore::get_params()
+{
+ upload_id = s->args.get("uploadId");
+
+ if (upload_id.empty()) {
+ ret = -ENOTSUP;
+ return ret;
+ }
+
+#define COMPLETE_MULTIPART_MAX_LEN (1024 * 1024) /* api defines max 10,000 parts, this should be enough */
+ ret = rgw_rest_read_all_input(s, &data, &len, COMPLETE_MULTIPART_MAX_LEN);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
int RGWListMultipart_ObjStore::get_params()
extern void rgw_flush_formatter(struct req_state *s,
ceph::Formatter *formatter);
+extern int rgw_rest_read_all_input(struct req_state *s, char **data, int *plen, int max_len);
+
class RESTArgs {
public:
static int get_string(struct req_state *s, const string& name, const string& def_val, string *val, bool *existed = NULL);