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 ¶ms ) {
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 chapmandcchap...@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