aports/main/nginx/nginx-upload-module~fixes.patch
Jakub Jirutka f3dbbda9f6 main/nginx: backport bugfixes for multiple third-party modules
The most important are bugfixes for http-shibboleth (segfault)
and http-lua (probably segfault too).
2023-05-26 14:23:20 +00:00

620 lines
22 KiB
Diff

git diff 2.3.0..643b4c1fa6993da6bc1f82e7121ca62a7696ee6b ngx_http_upload_module.c
--
commit 643b4c1fa6993da6bc1f82e7121ca62a7696ee6b
Author: Frankie Dintino <fdintino@gmail.com>
Date: Sun Jun 21 17:09:17 2020 -0400
Fix bug caused by uploading a single byte range
fixes #115
commit 1ac57ac4d37bfb0c09337f2eef3fab5a1c1e9a38
Author: Romain Pomier <romain@cardiologs.com>
Date: Wed Apr 8 18:42:38 2020 +0200
Handle quotes problems in Content-Type and Content-Disposition
commit 1b0c530a3abf5c8782feabcfa2e89a312687f968
Author: Frankie Dintino <fdintino@gmail.com>
Date: Mon Feb 10 12:48:52 2020 -0500
Fix issue where upload headers were only added to final request
fixes #124
commit a350ce9d6814438db56428ad6365db994dbd27f6
Author: Valery Kholodkov <valery@coldrift.com>
Date: Mon Nov 18 18:04:55 2019 +0100
Update read handler
commit 8d50edd32ae788c3e0c12fe1940007e9faa3f15d
Author: Demid Rudak <demid.r@didww.com>
Date: Mon Apr 1 15:37:52 2019 +0300
Fixed upload_aggregate_form_field 'upload_file_md5' calculation
commit 666428bf8ea3ee3e5bd40aaa693624234feb6da3
Author: Frankie Dintino <fdintino@gmail.com>
Date: Fri Aug 10 11:39:01 2018 -0400
Fix and add tests for upload_add_header
commit e8d93f8f37db62f2588c7b3a20c873514fce4f5d
Author: Frankie Dintino <fdintino@gmail.com>
Date: Fri Aug 10 11:35:16 2018 -0400
Remove unnecessary ngx_http_upload_variable_set function
commit 9c58c8ae9b3f4d44a28eebdffbdc1ab4224e3f90
Author: Frankie Dintino <fdintino@gmail.com>
Date: Mon Aug 6 09:38:52 2018 -0400
Fix bug when uc and lc hash aggregate fields present in the same request
--
diff --git a/ngx_http_upload_module.c b/ngx_http_upload_module.c
index 3ac3279..c51429f 100644
--- a/ngx_http_upload_module.c
+++ b/ngx_http_upload_module.c
@@ -55,8 +55,8 @@ typedef ngx_md5_t MD5_CTX;
#define X_SESSION_ID_STRING "X-Session-ID:"
#define FORM_DATA_STRING "form-data"
#define ATTACHMENT_STRING "attachment"
-#define FILENAME_STRING "filename=\""
-#define FIELDNAME_STRING "name=\""
+#define FILENAME_STRING "filename="
+#define FIELDNAME_STRING "name="
#define BYTES_UNIT_STRING "bytes "
#define NGX_UPLOAD_MALFORMED -11
@@ -302,8 +302,6 @@ static void *ngx_http_upload_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_upload_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child);
static ngx_int_t ngx_http_upload_add_variables(ngx_conf_t *cf);
-static void ngx_http_upload_variable_set(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_upload_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_upload_md5_variable(ngx_http_request_t *r,
@@ -326,6 +324,10 @@ static ngx_int_t ngx_http_upload_uint_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static char *ngx_http_upload_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+static ngx_int_t
+ngx_http_upload_process_field_templates(ngx_http_request_t *r,
+ ngx_http_upload_field_template_t *t, ngx_str_t *field_name, ngx_str_t *field_value);
+
static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u);
static void ngx_http_upload_finish_handler(ngx_http_upload_ctx_t *u);
static void ngx_http_upload_abort_handler(ngx_http_upload_ctx_t *u);
@@ -345,9 +347,7 @@ static ngx_int_t ngx_http_read_upload_client_request_body(ngx_http_request_t *r)
static char *ngx_http_upload_set_form_field(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-static char *ngx_http_upload_add_header(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static ngx_int_t ngx_http_upload_eval_path(ngx_http_request_t *r);
+ static ngx_int_t ngx_http_upload_eval_path(ngx_http_request_t *r);
static ngx_int_t ngx_http_upload_eval_state_path(ngx_http_request_t *r);
static char *ngx_http_upload_pass_form_field(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
@@ -666,7 +666,7 @@ static ngx_command_t ngx_http_upload_commands[] = { /* {{{ */
{ ngx_string("upload_add_header"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_TAKE2,
- ngx_http_upload_add_header,
+ ngx_http_upload_set_form_field,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_upload_loc_conf_t, header_templates),
NULL},
@@ -710,7 +710,7 @@ static ngx_http_variable_t ngx_http_upload_variables[] = { /* {{{ */
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
{ ngx_string("upload_content_type"),
- ngx_http_upload_variable_set,
+ NULL,
ngx_http_upload_variable,
(uintptr_t) offsetof(ngx_http_upload_ctx_t, content_type),
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
@@ -1052,18 +1052,14 @@ err:
static ngx_int_t ngx_http_upload_add_headers(ngx_http_request_t *r, ngx_http_upload_loc_conf_t *ulcf) { /* {{{ */
ngx_str_t name;
ngx_str_t value;
- ngx_http_upload_header_template_t *t;
+ ngx_http_upload_field_template_t *t;
ngx_table_elt_t *h;
ngx_uint_t i;
- if(ulcf->header_templates != NULL) {
+ if (ulcf->header_templates != NULL) {
t = ulcf->header_templates->elts;
- for(i = 0; i < ulcf->header_templates->nelts; i++) {
- if(ngx_http_complex_value(r, t->name, &name) != NGX_OK) {
- return NGX_ERROR;
- }
-
- if(ngx_http_complex_value(r, t->value, &value) != NGX_OK) {
+ for (i = 0; i < ulcf->header_templates->nelts; i++) {
+ if (ngx_http_upload_process_field_templates(r, &t[i], &name, &value) != NGX_OK) {
return NGX_ERROR;
}
@@ -1079,8 +1075,6 @@ static ngx_int_t ngx_http_upload_add_headers(ngx_http_request_t *r, ngx_http_upl
h->value.len = value.len;
h->value.data = value.data;
}
-
- t++;
}
}
@@ -1180,10 +1174,6 @@ static ngx_int_t ngx_http_upload_body_handler(ngx_http_request_t *r) { /* {{{ */
ngx_str_t dummy = ngx_string("<ngx_upload_module_dummy>");
ngx_table_elt_t *h;
- if(ngx_http_upload_add_headers(r, ulcf) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
if(ctx->prevent_output) {
r->headers_out.status = NGX_HTTP_CREATED;
@@ -1360,6 +1350,27 @@ static ngx_int_t ngx_http_upload_body_handler(ngx_http_request_t *r) { /* {{{ */
return rc;
} /* }}} */
+static ngx_int_t
+ngx_http_upload_process_field_templates(
+ ngx_http_request_t *r, ngx_http_upload_field_template_t *t,
+ ngx_str_t *name, ngx_str_t *value)
+{
+ if (t->field_lengths == NULL) {
+ *name = t->value.key;
+ } else if (ngx_http_script_run(r, name, t->field_lengths->elts, 0,
+ t->field_values->elts) == NULL) {
+ return NGX_UPLOAD_SCRIPTERROR;
+ }
+
+ if (t->value_lengths == NULL) {
+ *value = t->value.value;
+ } else if (ngx_http_script_run(r, value, t->value_lengths->elts, 0,
+ t->value_values->elts) == NULL) {
+ return NGX_UPLOAD_SCRIPTERROR;
+ }
+ return NGX_OK;
+}
+
static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u) { /* {{{ */
ngx_http_request_t *r = u->request;
ngx_http_upload_loc_conf_t *ulcf = ngx_http_get_module_loc_conf(r, ngx_http_upload_module);
@@ -1495,28 +1506,10 @@ static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u) { /* {{
t = ulcf->field_templates->elts;
for (i = 0; i < ulcf->field_templates->nelts; i++) {
+ rc = ngx_http_upload_process_field_templates(r, &t[i], &field_name, &field_value);
- if (t[i].field_lengths == NULL) {
- field_name = t[i].value.key;
- }else{
- if (ngx_http_script_run(r, &field_name, t[i].field_lengths->elts, 0,
- t[i].field_values->elts) == NULL)
- {
- rc = NGX_UPLOAD_SCRIPTERROR;
- goto cleanup_file;
- }
- }
-
- if (t[i].value_lengths == NULL) {
- field_value = t[i].value.value;
- }else{
- if (ngx_http_script_run(r, &field_value, t[i].value_lengths->elts, 0,
- t[i].value_values->elts) == NULL)
- {
- rc = NGX_UPLOAD_SCRIPTERROR;
- goto cleanup_file;
- }
- }
+ if(rc != NGX_OK)
+ goto cleanup_file;
rc = ngx_http_upload_append_field(u, &field_name, &field_value);
@@ -1603,6 +1596,11 @@ static ngx_int_t ngx_http_upload_start_handler(ngx_http_upload_ctx_t *u) { /* {{
u->discard_data = 1;
}
+
+ if(ngx_http_upload_add_headers(r, ulcf) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
return NGX_OK;
cleanup_file:
@@ -1697,25 +1695,10 @@ static void ngx_http_upload_finish_handler(ngx_http_upload_ctx_t *u) { /* {{{ */
if(ulcf->aggregate_field_templates) {
af = ulcf->aggregate_field_templates->elts;
for (i = 0; i < ulcf->aggregate_field_templates->nelts; i++) {
-
- if (af[i].field_lengths == NULL) {
- aggregate_field_name = af[i].value.key;
- }else{
- if (ngx_http_script_run(r, &aggregate_field_name, af[i].field_lengths->elts, 0,
- af[i].field_values->elts) == NULL)
- {
- goto rollback;
- }
- }
-
- if (af[i].value_lengths == NULL) {
- aggregate_field_value = af[i].value.value;
- }else{
- if (ngx_http_script_run(r, &aggregate_field_value, af[i].value_lengths->elts, 0,
- af[i].value_values->elts) == NULL)
- {
- goto rollback;
- }
+ rc = ngx_http_upload_process_field_templates(r, &af[i], &aggregate_field_name,
+ &aggregate_field_value);
+ if (rc != NGX_OK) {
+ goto rollback;
}
rc = ngx_http_upload_append_field(u, &aggregate_field_name, &aggregate_field_value);
@@ -2001,7 +1984,7 @@ ngx_http_upload_buf_merge_range(ngx_http_upload_merger_state_t *ms, ngx_http_upl
return NGX_ERROR;
}
- if(ms->current_range_n.start >= ms->current_range_n.end || ms->current_range_n.start >= ms->current_range_n.total
+ if(ms->current_range_n.start > ms->current_range_n.end || ms->current_range_n.start > ms->current_range_n.total
|| ms->current_range_n.end > ms->current_range_n.total)
{
ngx_log_debug3(NGX_LOG_DEBUG_CORE, ms->log, 0,
@@ -2398,21 +2381,6 @@ ngx_http_upload_add_variables(ngx_conf_t *cf)
return NGX_OK;
} /* }}} */
-static void /* {{{ ngx_http_upload_variable_set */
-ngx_http_upload_variable_set(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
-{
- ngx_str_t *s;
- ngx_http_upload_ctx_t *u;
-
- u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
-
- s = (ngx_str_t *) ((char *) u + data);
-
- s->len = v->len;
- s->data = v->data;
-} /* }}} */
-
static ngx_int_t /* {{{ ngx_http_upload_variable */
ngx_http_upload_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
@@ -2434,88 +2402,78 @@ ngx_http_upload_variable(ngx_http_request_t *r,
return NGX_OK;
} /* }}} */
-static ngx_int_t /* {{{ ngx_http_upload_md5_variable */
-ngx_http_upload_md5_variable(ngx_http_request_t *r,
- ngx_http_variable_value_t *v, uintptr_t data)
+static ngx_int_t
+ngx_http_upload_hash_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data, u_char *digest,
+ ngx_uint_t digest_len)
{
ngx_uint_t i;
- ngx_http_upload_ctx_t *u;
u_char *c;
+ u_char *p;
u_char *hex_table;
- u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
-
- if(u->md5_ctx == NULL || u->partial_content) {
- v->not_found = 1;
- return NGX_OK;
- }
-
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
hex_table = (u_char*)data;
- c = u->md5_ctx->md5_digest + MD5_DIGEST_LENGTH * 2;
- i = MD5_DIGEST_LENGTH;
+ p = ngx_palloc(r->pool, digest_len * 2);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ c = p + digest_len * 2;
+ i = digest_len;
do{
i--;
- *--c = hex_table[u->md5_ctx->md5_digest[i] & 0xf];
- *--c = hex_table[u->md5_ctx->md5_digest[i] >> 4];
+ *--c = hex_table[digest[i] & 0xf];
+ *--c = hex_table[digest[i] >> 4];
}while(i != 0);
- v->data = u->md5_ctx->md5_digest;
- v->len = MD5_DIGEST_LENGTH * 2;
+ v->data = c;
+ v->len = digest_len * 2;
return NGX_OK;
} /* }}} */
-static ngx_int_t /* {{{ ngx_http_upload_sha1_variable */
-ngx_http_upload_sha1_variable(ngx_http_request_t *r,
+static ngx_int_t /* {{{ ngx_http_upload_md5_variable */
+ngx_http_upload_md5_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
- ngx_uint_t i;
ngx_http_upload_ctx_t *u;
- u_char *c;
- u_char *hex_table;
u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
- if(u->sha1_ctx == NULL || u->partial_content) {
+ if(u->md5_ctx == NULL || u->partial_content) {
v->not_found = 1;
return NGX_OK;
}
+ return ngx_http_upload_hash_variable(r, v, data, u->md5_ctx->md5_digest, MD5_DIGEST_LENGTH);
+} /* }}} */
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- hex_table = (u_char*)data;
- c = u->sha1_ctx->sha1_digest + SHA_DIGEST_LENGTH * 2;
-
- i = SHA_DIGEST_LENGTH;
+static ngx_int_t /* {{{ ngx_http_upload_sha1_variable */
+ngx_http_upload_sha1_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ ngx_http_upload_ctx_t *u;
- do{
- i--;
- *--c = hex_table[u->sha1_ctx->sha1_digest[i] & 0xf];
- *--c = hex_table[u->sha1_ctx->sha1_digest[i] >> 4];
- }while(i != 0);
+ u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
- v->data = u->sha1_ctx->sha1_digest;
- v->len = SHA_DIGEST_LENGTH * 2;
+ if(u->sha1_ctx == NULL || u->partial_content) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
- return NGX_OK;
+ return ngx_http_upload_hash_variable(r, v, data, u->sha1_ctx->sha1_digest, SHA_DIGEST_LENGTH);
} /* }}} */
static ngx_int_t /* {{{ ngx_http_upload_sha256_variable */
ngx_http_upload_sha256_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
- ngx_uint_t i;
ngx_http_upload_ctx_t *u;
- u_char *c;
- u_char *hex_table;
u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
@@ -2524,35 +2482,14 @@ ngx_http_upload_sha256_variable(ngx_http_request_t *r,
return NGX_OK;
}
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- hex_table = (u_char*)data;
- c = u->sha256_ctx->sha256_digest + SHA256_DIGEST_LENGTH * 2;
-
- i = SHA256_DIGEST_LENGTH;
-
- do{
- i--;
- *--c = hex_table[u->sha256_ctx->sha256_digest[i] & 0xf];
- *--c = hex_table[u->sha256_ctx->sha256_digest[i] >> 4];
- }while(i != 0);
-
- v->data = u->sha256_ctx->sha256_digest;
- v->len = SHA256_DIGEST_LENGTH * 2;
-
- return NGX_OK;
+ return ngx_http_upload_hash_variable(r, v, data, u->sha256_ctx->sha256_digest, SHA256_DIGEST_LENGTH);
} /* }}} */
static ngx_int_t /* {{{ ngx_http_upload_sha512_variable */
ngx_http_upload_sha512_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
- ngx_uint_t i;
ngx_http_upload_ctx_t *u;
- u_char *c;
- u_char *hex_table;
u = ngx_http_get_module_ctx(r, ngx_http_upload_module);
@@ -2561,25 +2498,7 @@ ngx_http_upload_sha512_variable(ngx_http_request_t *r,
return NGX_OK;
}
- v->valid = 1;
- v->no_cacheable = 0;
- v->not_found = 0;
-
- hex_table = (u_char*)data;
- c = u->sha512_ctx->sha512_digest + SHA512_DIGEST_LENGTH * 2;
-
- i = SHA512_DIGEST_LENGTH;
-
- do{
- i--;
- *--c = hex_table[u->sha512_ctx->sha512_digest[i] & 0xf];
- *--c = hex_table[u->sha512_ctx->sha512_digest[i] >> 4];
- }while(i != 0);
-
- v->data = u->sha512_ctx->sha512_digest;
- v->len = SHA512_DIGEST_LENGTH * 2;
-
- return NGX_OK;
+ return ngx_http_upload_hash_variable(r, v, data, u->sha512_ctx->sha512_digest, SHA512_DIGEST_LENGTH);
} /* }}} */
static ngx_int_t /* {{{ ngx_http_upload_crc32_variable */
@@ -2922,73 +2841,6 @@ ngx_http_upload_pass_form_field(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
} /* }}} */
-static char * /* {{{ ngx_http_upload_add_header */
-ngx_http_upload_add_header(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_str_t *value;
- ngx_http_upload_header_template_t *h;
- ngx_array_t **field;
- ngx_http_compile_complex_value_t ccv;
-
- field = (ngx_array_t**) (((u_char*)conf) + cmd->offset);
-
- value = cf->args->elts;
-
- /*
- * Add new entry to header template list
- */
- if (*field == NULL) {
- *field = ngx_array_create(cf->pool, 1,
- sizeof(ngx_http_upload_header_template_t));
- if (*field == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- h = ngx_array_push(*field);
- if (h == NULL) {
- return NGX_CONF_ERROR;
- }
-
- /*
- * Compile header name
- */
- h->name = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if(h->name == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = h->name;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- /*
- * Compile header value
- */
- h->value = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if(h->value == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[2];
- ccv.complex_value = h->value;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
-} /* }}} */
-
static char * /* {{{ ngx_http_upload_cleanup */
ngx_http_upload_cleanup(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
@@ -3599,6 +3451,8 @@ ngx_http_do_read_upload_client_request_body(ngx_http_request_t *r)
ngx_del_timer(c->read);
}
+ r->read_event_handler = ngx_http_block_reading;
+
rc = ngx_http_process_request_body(r, u->to_write);
switch(rc) {
@@ -3667,16 +3521,14 @@ static ngx_int_t upload_parse_content_disposition(ngx_http_upload_ctx_t *upload_
if(filename_start != 0) {
- filename_start += sizeof(FILENAME_STRING)-1;
-
- filename_end = filename_start + strcspn(filename_start, "\"");
+ filename_start += sizeof(FILENAME_STRING) - 1;
- if(*filename_end != '\"') {
- ngx_log_debug0(NGX_LOG_DEBUG_CORE, upload_ctx->log, 0,
- "malformed filename in part header");
- return NGX_UPLOAD_MALFORMED;
+ if (*filename_start == '\"') {
+ filename_start++;
}
+ filename_end = filename_start + strcspn(filename_start, "\";");
+
/*
* IE sends full path, strip path from filename
* Also strip all UNIX path references
@@ -3703,16 +3555,14 @@ static ngx_int_t upload_parse_content_disposition(ngx_http_upload_ctx_t *upload_
// }while((fieldname_start != 0) && (fieldname_start + sizeof(FIELDNAME_STRING) - 1 == filename_start));
if(fieldname_start != 0) {
- fieldname_start += sizeof(FIELDNAME_STRING)-1;
+ fieldname_start += sizeof(FIELDNAME_STRING) - 1;
- if(fieldname_start != filename_start) {
- fieldname_end = fieldname_start + strcspn(fieldname_start, "\"");
+ if (*fieldname_start == '\"') {
+ fieldname_start++;
+ }
- if(*fieldname_end != '\"') {
- ngx_log_error(NGX_LOG_ERR, upload_ctx->log, 0,
- "malformed fieldname in part header");
- return NGX_UPLOAD_MALFORMED;
- }
+ if(fieldname_start != filename_start) {
+ fieldname_end = fieldname_start + strcspn(fieldname_start, "\";");
upload_ctx->field_name.len = fieldname_end - fieldname_start;
upload_ctx->field_name.data = ngx_pcalloc(upload_ctx->request->pool, upload_ctx->field_name.len + 1);
@@ -4087,6 +3937,12 @@ static ngx_int_t upload_parse_request_headers(ngx_http_upload_ctx_t *upload_ctx,
boundary_start_ptr += sizeof(BOUNDARY_STRING) - 1;
boundary_end_ptr = boundary_start_ptr + strcspn((char*)boundary_start_ptr, " ;\n\r");
+ // Handle quoted boundaries
+ if ((boundary_end_ptr - boundary_start_ptr) >= 2 && boundary_start_ptr[0] == '"' && *(boundary_end_ptr - 1) == '"') {
+ boundary_start_ptr++;
+ boundary_end_ptr--;
+ }
+
if(boundary_end_ptr == boundary_start_ptr) {
ngx_log_debug0(NGX_LOG_DEBUG_CORE, upload_ctx->log, 0,
"boundary is empty");