diff options
Diffstat (limited to 'src/sliding_buffer.c')
-rw-r--r-- | src/sliding_buffer.c | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/src/sliding_buffer.c b/src/sliding_buffer.c index 1adade5..70d64a5 100644 --- a/src/sliding_buffer.c +++ b/src/sliding_buffer.c @@ -129,32 +129,37 @@ s_buffer_read (sliding_buffer_t * sbuf, char *matchstr) */ pos = 0; len = sbuf->bufsize - (int) (sbuf->ptr - sbuf->buf) - strlen (matchstr); - /* On a short read or very long matchstr, its possible to force len < 0 - That is bad. */ - if ( len < 0 ) - { - die_with_message ( NULL, NULL, "Short Read or MIME decode failure" ); - } - while (memcmp (matchstr, sbuf->ptr + pos, strlen (matchstr)) && (pos < len)) - { - pos++; - } - - /* - * if we found it - */ - if (pos < len) - { - sbuf->len = pos; - sbuf->segment = sbuf->ptr; - sbuf->ptr = sbuf->segment + pos + strlen (matchstr); - return -1; - } - - if (sbuf->eof) - { - len += strlen (matchstr); - } - + /* a malicious client can send a matchstr longer than the actual content body + do not allow reads beyond the buffer limits + */ + len = ( len < 0 ) ? 0 : len; + + /* if have a matchstr, look for it, otherwise return the chunk */ + if ( strlen(matchstr) > 0 ) { + + while (memcmp (matchstr, sbuf->ptr + pos, strlen (matchstr)) && (pos < len)) + { + pos++; + } + + /* + * if we found it + */ + if (pos < len) + { + sbuf->len = pos; + sbuf->segment = sbuf->ptr; + sbuf->ptr = sbuf->segment + pos + strlen (matchstr); + return -1; + } + + + if (sbuf->eof) + { + len += strlen (matchstr); + } + + } /* * ran off the end, didn't find the matchstr */ |