Intro
This one has been bugging be for ages, My application would fault at random times with, "bad boundary end of body part" from the read_multipart in ActionController. I finally took a very close look.
I have a form, with a quite few fields, uses can also add attachments so the post is via multipart.
I worked out the odds of this happening (once I found a solution) are approx 1 in 120, and was suprised this has not cropped up before. There cant be many rails apps, with large data entry screens using multipart out there
What happens in read_multipart
- If your post content is greater than 10240 bytes, read_multipart fills up buff with 10240 bytes
- The code to extract params, will see the "--boundary[CR][LF]" and extract the param and delete up to the bounday, and then loop for the next param
- But if the buff ends with "--boundary[CR][LF]", on extracing the param the buff is zero length
- But for some reason, If buff is zero a break is issued and then a fault happens
What wrong
- A check for zero bytes read, is performed previously in the code, why do it again??
- I cant figure out why you would check the buff for zero length??, when it is valid to be zero.
The fix
- Dont break if buff is zero length !!
Edit /ruby/lib/ruby/gems/1.8/gems/actionpack-2.x.x/lib/action_controller/request.rb
def read_multipart(body, boundary, content_length, env) etc ... buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/n) do content.print $1 if "--" == $2 content_length = -1 end boundary_end = $2.dup "" end etc ... # break if buf.size == 0 # Dont break on zero, as buf could end on a boundary !!! resulting in empty buff break if content_length == -1 etc...
Rails Ticket
Checkout rails ticket 10886 just lodged for updates.Finally
If some one knows why the buff zero length is/was needed, I would like to know