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





Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.