From 3632dae0245ea502c4cf17189b95018867f0caf9 Mon Sep 17 00:00:00 2001 From: brectanus Date: Fri, 30 May 2008 20:07:47 +0000 Subject: [PATCH] Backported changeset:1056 to 2.5.x which handles a lacking new line after the final multipart boundary. See #502. --- CHANGES | 3 +++ apache2/msc_multipart.c | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index 34db2233..b31beabb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ 30 May 2008 - 2.5.5-dev1 ------------------------ +* Handle lack of a new line after the final boundary in a multipart request. + This fixes the reported WordPress Flash file uploader problem. + * Fixed issue with multithreaded servers where concurrent XML processing could crash the web server (at least under Windows). diff --git a/apache2/msc_multipart.c b/apache2/msc_multipart.c index d261bc5c..ad990385 100644 --- a/apache2/msc_multipart.c +++ b/apache2/msc_multipart.c @@ -820,18 +820,43 @@ int multipart_init(modsec_rec *msr, char **error_msg) { } /** - * + * Finalise multipart processing. This method is invoked at the end, when it + * is clear that there is no more data to be processed. */ -int multipart_complete(modsec_rec *msr, char **error_log) { +int multipart_complete(modsec_rec *msr, char **error_msg) { if (msr->mpd == NULL) return 1; if ((msr->mpd->seen_data != 0)&&(msr->mpd->is_complete == 0)) { if (msr->mpd->boundary_count > 0) { - *error_log = apr_psprintf(msr->mp, "Multipart: Final boundary missing."); + /* Check if we have the final boundary (that we haven't + * processed yet) in the buffer. + */ + if (msr->mpd->buf_contains_line) { + if ( ((MULTIPART_BUF_SIZE - msr->mpd->bufleft) == (4 + strlen(msr->mpd->boundary))) + && (*(msr->mpd->buf) == '-')&&(*(msr->mpd->buf + 1) == '-') + && (strncmp(msr->mpd->buf + 2, msr->mpd->boundary, strlen(msr->mpd->boundary)) == 0) + && (*(msr->mpd->buf + 2 + strlen(msr->mpd->boundary)) == '-') + && (*(msr->mpd->buf + 2 + strlen(msr->mpd->boundary) + 1) == '-') ) + { + /* Looks like the final boundary - process it. */ + if (multipart_process_boundary(msr, 1 /* final */, error_msg) < 0) { + msr->mpd->flag_error = 1; + return -1; + } + + /* The payload is complete after all. */ + msr->mpd->is_complete = 1; + } + } + + if (msr->mpd->is_complete == 0) { + *error_msg = apr_psprintf(msr->mp, "Multipart: Final boundary missing."); + return -1; + } } else { - *error_log = apr_psprintf(msr->mp, "Multipart: No boundaries found in payload."); + *error_msg = apr_psprintf(msr->mp, "Multipart: No boundaries found in payload."); + return -1; } - return -1; } return 1;