curl / Mailing Lists / curl-library / Single Mail
Buy commercial curl support from WolfSSL. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder himself.

Re: Serialisation problem

From: David Chapman via curl-library <curl-library_at_lists.haxx.se>
Date: Thu, 9 Jun 2022 09:42:08 -0700

Looks like a C++ temporary variable lifetime problem.  See below.

On 6/9/2022 9:17 AM, J via curl-library wrote:
> Hi,
>
> I'm struggling to understand what the issue might be, but I'm getting
> this error:
>
> {"error-code":"Internal Error","error-message":"JSON parse error:
> Unexpected character ('/' (code 47)): maybe a (non-standard) comment?
> (not recognized as one since Feature 'ALLOW_COMMENTS' not enabled for
> parser); nested exception is
> com.fasterxml.jackson.core.JsonParseException: Unexpected character
> ('/' (code 47)): maybe a (non-standard) comment? (not recognized as
> one since Feature 'ALLOW_COMMENTS' not enabled for parser)\n at
> [Source: (PushbackInputStream); line: 1, column: 2]","request-id":""}
>
> When I
> curl_easy_setopt( curl, CURLOPT_POSTFIELDS, s2 );
> But for some reason, the error does not occur when I use
> curl_easy_setopt( curl, CURLOPT_POSTFIELDS, s1 );
> But BOTH strings are nul-terminated and contain the exact same data:
> Contents of string: /(s1)/ 123 34 104 111 115 116 34 58 34 49 57 50 46
> 49 54 56 46 49 57 53 46 49 50 34 125 Contents of string: /(s2)/ 123 34
> 104 111 115 116 34 58 34 49 57 50 46 49 54 56 46 49 57 53 46 49 50 34 125
> What am I not understanding here? The strings are single-byte
> characters, so might it be a problem with some internal
> unicode-conversion?
> Here is the complete code:
> voiddumpstring( constchar*p ) {
> std::cerr <<EOL;
> std::cerr <<"Contents of string:"EOL;
> for( ; *p; p++ ) {
> std::cout <<(int)*p <<" ";
> }
> std::cerr <<EOL;
> }
> boolExecuteCommand( constchar*token, constchar*nodename,
> constchar*command, constchar*tenant, constcmd_params &params ) {
> CURL * curl;
> CURLcode res;
> curl = curl_easy_init();
> if( curl ) {
> curl_easy_setopt( curl, CURLOPT_URL, ( (
> (std::string)"https://ubihub.cityiq-dvp.io/"+tenant
> +"/v1.0/ecs/command/") +nodename +"\?commandId="+command
> +"&mode=sync").c_str() );

Try storing the result of the string appends in a variable.  You are
passing a c_str() of a temporary C++ variable and the compiler may
choose to call its destructor before calling curl_easy_setopt().

         std::string foo(( (
(std::string)"https://ubihub.cityiq-dvp.io/"+tenant
+"/v1.0/ecs/command/") +nodename +"\?commandId="+command
+"&mode=sync").c_str() );
         curl_easy_setopt( curl, CURLOPT_URL, foo.c_str() );

This way the C++ value is guaranteed to have a lifetime longer than the
call to curl_easy_setopt().

You will of course need to do this everywhere; I show only one example.


> curl_easy_setopt( curl, CURLOPT_FOLLOWLOCATION, 1L);
> structcurl_slist *headers = NULL;
> headers = curl_slist_append( headers, ( ( (std::string)"Authorization:
> Bearer ") +token ).c_str() );
> if( params.size() ) {
> headers = curl_slist_append( headers, "Content-Type: application/json");
> Json::StreamWriterBuilder builder;
> builder["indentation"]="";
> Json::Value values;
> for( size_tu = 0; u < params.size(); u++ ) {
> std::size_tequalpos = params.at <http://params.at>( u ).find( "=");
> if( std::string::npos != equalpos ) {
> std::string key = params.at <http://params.at>( u ).substr( 0, equalpos );
> std::string value = params.at <http://params.at>( u ).substr( equalpos
> + 1);
> values[key]=value;
> }
> }
> std::string serialized = Json::writeString( builder, values );
> constchar* s1 = "{\"host\":\"192.168.195.12\"}";
> constchar* s2 = serialized.c_str();
> dumpstring( s1 );
> dumpstring( s2 );
> curl_easy_setopt( curl, CURLOPT_POSTFIELDS, s2 );
> }
> curl_easy_setopt( curl, CURLOPT_HTTPHEADER, headers );
> curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "POST");
> res = curl_easy_perform( curl );
> curl_easy_cleanup( curl );
> if( CURLE_OK!= res ) {
> std::cerr <<"curl_easy_perform() failed: "<<curl_easy_strerror( res )
> <<EOL;
> returnfalse;
> }
> }
> returntrue;
> }
> As I wrote above, both potential strings are dumped at runtime and
> both contain the same characters.
> Any help is appreciated.
> Thanks
>


-- 
     David Chapmandcchapman_at_acm.org
     Chapman Consulting -- San Jose, CA
     EDA Software Developer, Expert Witness
     www.chapman-consulting-sj.com
     2018-2019 Chair, IEEE Consultants' Network of Silicon Valley


-- 
Unsubscribe: https://lists.haxx.se/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html
Received on 2022-06-09