@@ -586,47 +586,46 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
586586 return debug != nullptr ;
587587 const char *rest_url = pos + strlen (method_name) + 7 ;
588588 if (*rest_url == ' &' ) ++rest_url;
589- call_args.Form (" \" %s\" " , rest_url);
589+ call_args.Append (" \" " );
590+ call_args.Append (DecodeUrlOptionValue (rest_url, kTRUE ));
591+ call_args.Append (" \" " );
590592 break ;
591593 }
592594
593595 TString sval;
594596 const char *val = url.GetValueFromOptions (arg->GetName ());
595- if (val) {
596- sval = DecodeUrlOptionValue (val, kFALSE );
597- val = sval. Data ();
598- }
597+ if (val)
598+ sval = DecodeUrlOptionValue (val, kTRUE );
599+
600+ Bool_t sanitize_numeric = kFALSE ;
599601
600- if ((val != nullptr ) && ( strcmp (val, " _this_" ) == 0 ) ) {
602+ if (sval == " _this_" ) {
601603 // special case - object itself is used as argument
602604 sval.Form (" (%s*)0x%zx" , obj_cl->GetName (), (size_t )obj_ptr);
603- val = sval.Data ();
604- } else if ((val != nullptr ) && (fCurrentArg != nullptr ) && (fCurrentArg ->GetPostData () != nullptr )) {
605+ } else if ((fCurrentArg != nullptr ) && (fCurrentArg ->GetPostData () != nullptr )) {
605606 // process several arguments which are specific for post requests
606- if (strcmp (val, " _post_object_xml_ " ) == 0 ) {
607+ if (sval == " _post_object_xml_ " ) {
607608 // post data has extra 0 at the end and can be used as null-terminated string
608609 post_obj = TBufferXML::ConvertFromXML ((const char *)fCurrentArg ->GetPostData ());
609- if (!post_obj) {
610+ if (!post_obj)
610611 sval = " 0" ;
611- } else {
612+ else {
612613 sval.Form (" (%s*)0x%zx" , post_obj->ClassName (), (size_t )post_obj);
613614 if (url.HasOption (" _destroy_post_" ))
614615 garbage.Add (post_obj);
615616 }
616- val = sval.Data ();
617- } else if (strcmp (val, " _post_object_json_" ) == 0 ) {
617+ } else if (sval == " _post_object_json_" ) {
618618 // post data has extra 0 at the end and can be used as null-terminated string
619619 post_obj = TBufferJSON::ConvertFromJSON ((const char *)fCurrentArg ->GetPostData ());
620- if (!post_obj) {
620+ if (!post_obj)
621621 sval = " 0" ;
622- } else {
622+ else {
623623 sval.Form (" (%s*)0x%zx" , post_obj->ClassName (), (size_t )post_obj);
624624 if (url.HasOption (" _destroy_post_" ))
625625 garbage.Add (post_obj);
626626 }
627- val = sval.Data ();
628- } else if ((strcmp (val, " _post_object_" ) == 0 ) && url.HasOption (" _post_class_" )) {
629- TString clname = url.GetValueFromOptions (" _post_class_" );
627+ } else if ((sval == " _post_object_" ) && url.HasOption (" _post_class_" )) {
628+ TString clname = DecodeUrlOptionValue (url.GetValueFromOptions (" _post_class_" ), kTRUE );
630629 TClass *arg_cl = gROOT ->GetClass (clname, kTRUE , kTRUE );
631630 if ((arg_cl != nullptr ) && (arg_cl->GetBaseClassOffset (TObject::Class ()) == 0 ) && (post_obj == nullptr )) {
632631 post_obj = (TObject *)arg_cl->New ();
@@ -643,38 +642,61 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
643642 garbage.Add (post_obj);
644643 }
645644 }
646- sval.Form (" (%s*)0x%zx" , clname.Data (), (size_t )post_obj);
647- val = sval.Data ();
648- } else if (strcmp (val, " _post_data_" ) == 0 ) {
645+ if (!post_obj)
646+ sval = " 0" ;
647+ else
648+ sval.Form (" (%s*)0x%zx" , clname.Data (), (size_t )post_obj);
649+ } else if (sval == " _post_data_" )
649650 sval.Form (" (void*)0x%zx" , (size_t )fCurrentArg ->GetPostData ());
650- val = sval.Data ();
651- } else if (strcmp (val, " _post_length_" ) == 0 ) {
651+ else if (sval == " _post_length_" )
652652 sval.Form (" %ld" , (long )fCurrentArg ->GetPostDataLength ());
653- val = sval.Data ();
654- }
655- }
653+ else
654+ sanitize_numeric = kTRUE ;
655+ } else
656+ sanitize_numeric = kTRUE ;
656657
657- if (!val )
658- val = arg->GetDefault ();
658+ if (sval. IsNull () && arg-> GetDefault () )
659+ sval = arg->GetDefault ();
659660
660661 if (debug)
661- debug->append (Form (" Argument:%s Type:%s Value:%s \n " , arg->GetName (), arg->GetFullTypeName (),
662- val ? val : " <missed>" ));
663- if (!val)
664- return debug != nullptr ;
662+ debug->append (
663+ TString::Format (" Argument:%s Type:%s Value:%s \n " , arg->GetName (), arg->GetFullTypeName (), sval.Data ())
664+ .Data ());
665665
666666 if (call_args.Length () > 0 )
667667 call_args += " , " ;
668668
669- if ((strcmp (arg->GetFullTypeName (), " const char*" ) == 0 ) || (strcmp (arg->GetFullTypeName (), " Option_t*" ) == 0 )) {
670- int len = strlen (val);
671- if ((strlen (val) < 2 ) || (*val != ' \" ' ) || (val[len - 1 ] != ' \" ' ))
672- call_args.Append (TString::Format (" \" %s\" " , val));
673- else
674- call_args.Append (val);
669+ Bool_t isstr = (strcmp (arg->GetFullTypeName (), " const char*" ) == 0 ) ||
670+ (strcmp (arg->GetFullTypeName (), " Option_t*" ) == 0 ) ||
671+ (strcmp (arg->GetFullTypeName (), " string" ) == 0 );
672+
673+ if (isstr) {
674+ // check that quotes provided for the string argument
675+ // all special characters were escaped before
676+ if (sval.IsNull ())
677+ sval = " \"\" " ;
678+ else {
679+ if (sval[0 ] != ' "' )
680+ sval.Prepend (" \" " );
681+ if (sval[sval.Length () - 1 ] != ' "' )
682+ sval.Append (" \" " );
683+ }
675684 } else {
676- call_args.Append (val);
685+ // for numeric types keep only numeric and alphabetic characters
686+ // exclude others - especially remove all escape characters
687+ if (sanitize_numeric) {
688+ TString sanitized;
689+ for (Size_t i = 0 ; i < sval.Length (); ++i) {
690+ if (std::isalnum (sval[i]) || std::strchr (" .:+-" , sval[i]))
691+ sanitized.Append (sval[i]);
692+ }
693+ sval = sanitized;
694+ }
695+ if (sval.IsNull ())
696+ sval = " 0" ;
677697 }
698+
699+ call_args.Append (sval);
678700 }
679701
680702 TMethodCall *call = nullptr ;
0 commit comments