Menu

#150 Bug in multipart_parser.h, parse_pair

cppcms-2.0
closed
None
1
2018-02-02
2018-01-20
Anonymous
No

There is a bug in private/multipart_parser.h in the parse_pair function on line 318. After parsing a unquoted name/value pair, the position of the iterator is not updated to the point after the value. When it tries to parse the next name/value pair in the same header, it fails because the current position is not on the semi-colon, it's still at the beginning of the previous value.

The error is the line "tmp=p;", which, compared to the code that deals with quoted values (line 310), should be "p=tmp;"

Discussion

  • Artyom Beilis

    Artyom Beilis - 2018-01-20

    Can you provide exact example so I can debug it?

     
  • Anonymous

    Anonymous - 2018-01-20

    I found this bug when POSTing a file using C#'s HttpClient (so the only example I have is C# code).

    If it's any use, here it is. The way this is set up, the Content-Disposition's name="works" will parse correctly (it's quoted) but the filename=fails will not (it's unquoted). I compiled this against .NET 4.0.

    Thank you.

    using System;
    using System.Net.Http;
    namespace CPPCMSTest
    { class Program
    { static void Main(string[] args)
    { using(var client = new HttpClient())
    using(var content = new MultipartFormDataContent())
    { content.Add(new StringContent("test"), "\"works\"", "fails");
    Console.WriteLine
    ( client
    . PostAsync("http://localhost:8080", content)
    . Result
    . Content
    . ReadAsStringAsync()
    . Result
    );
    }
    }
    }
    }

     
  • Anonymous

    Anonymous - 2018-01-20

    I used the following code to test CPPCMS:

    #include <cppcms/service.h>
    #include <cppcms/applications_pool.h>
    #include <cppcms/application.h>
    #include <cppcms/http_request.h>
    #include <iostream>
    #include <string>
    class Application : public cppcms::application
    {  public:
       Application
       (  cppcms::service & service
       ): cppcms::application(service)
       { }
       virtual void main
       (  std::string url
       ){ std::cout
          << "Request for " << url << std::endl
          << "  Uploaded file count "
          << request().files().size()
          << std::endl;
    };
    int main(int argc, char * * args)
    { cppcms::service service(argc, args);
      service.applications_pool().mount
      ( cppcms::applications_factory<Application>()
      );
      service.run();
      return 0;
    }
    

    ...with the following config.js:

    { "service":
      { "api": "http"
      , "port": 8080
      , "ip": "10.0.0.4"
      }
    , "http": { "script": "/" }
    , "logging": { "level": "debug" }
    }
    

    The bug can be found by TELNETing the following. It will fail when it attempts to parse the "f" in filename (because name=test is not quoted). It will work if it's updated to name="test"

    POST / HTTP/1.1
    Content-Type: multipart/form-data; boundary=---------------------------41184676334
    Content-Length: 106
    
    -----------------------------41184676334
    Content-Disposition: form-data; name=test; filename=test.txt
    
     
  • Artyom Beilis

    Artyom Beilis - 2018-02-02
    • status: open --> closed
    • assigned_to: Artyom Beilis
     
  • Artyom Beilis

    Artyom Beilis - 2018-02-02

    Thank you very much for this detailed bug report with accurate directions of fixing it.

    It was resolved in changeset 9f58f3822f355b48f33e45a7922c13269569f94b at github / master

    Feel free to reopen if anything is still wrong.

     

Anonymous
Anonymous

Add attachments
Cancel