@@ -625,47 +625,46 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
625625 return debug != nullptr ;
626626 const char *rest_url = pos + strlen (method_name) + 7 ;
627627 if (*rest_url == ' &' ) ++rest_url;
628- call_args.Form (" \" %s\" " , rest_url);
628+ call_args.Append (" \" " );
629+ call_args.Append (DecodeUrlOptionValue (rest_url, kTRUE ));
630+ call_args.Append (" \" " );
629631 break ;
630632 }
631633
632634 TString sval;
633635 const char *val = url.GetValueFromOptions (arg->GetName ());
634- if (val) {
635- sval = DecodeUrlOptionValue (val, kFALSE );
636- val = sval. Data ();
637- }
636+ if (val)
637+ sval = DecodeUrlOptionValue (val, kTRUE );
638+
639+ Bool_t sanitize_numeric = kFALSE ;
638640
639- if ((val != nullptr ) && ( strcmp (val, " _this_" ) == 0 ) ) {
641+ if (sval == " _this_" ) {
640642 // special case - object itself is used as argument
641643 sval.Form (" (%s*)0x%zx" , obj_cl->GetName (), (size_t )obj_ptr);
642- val = sval.Data ();
643- } else if ((val != nullptr ) && (fCurrentArg != nullptr ) && (fCurrentArg ->GetPostData () != nullptr )) {
644+ } else if ((fCurrentArg != nullptr ) && (fCurrentArg ->GetPostData () != nullptr )) {
644645 // process several arguments which are specific for post requests
645- if (strcmp (val, " _post_object_xml_ " ) == 0 ) {
646+ if (sval == " _post_object_xml_ " ) {
646647 // post data has extra 0 at the end and can be used as null-terminated string
647648 post_obj = TBufferXML::ConvertFromXML ((const char *)fCurrentArg ->GetPostData ());
648- if (!post_obj) {
649+ if (!post_obj)
649650 sval = " 0" ;
650- } else {
651+ else {
651652 sval.Form (" (%s*)0x%zx" , post_obj->ClassName (), (size_t )post_obj);
652653 if (url.HasOption (" _destroy_post_" ))
653654 garbage.Add (post_obj);
654655 }
655- val = sval.Data ();
656- } else if (strcmp (val, " _post_object_json_" ) == 0 ) {
656+ } else if (sval == " _post_object_json_" ) {
657657 // post data has extra 0 at the end and can be used as null-terminated string
658658 post_obj = TBufferJSON::ConvertFromJSON ((const char *)fCurrentArg ->GetPostData ());
659- if (!post_obj) {
659+ if (!post_obj)
660660 sval = " 0" ;
661- } else {
661+ else {
662662 sval.Form (" (%s*)0x%zx" , post_obj->ClassName (), (size_t )post_obj);
663663 if (url.HasOption (" _destroy_post_" ))
664664 garbage.Add (post_obj);
665665 }
666- val = sval.Data ();
667- } else if ((strcmp (val, " _post_object_" ) == 0 ) && url.HasOption (" _post_class_" )) {
668- TString clname = url.GetValueFromOptions (" _post_class_" );
666+ } else if ((sval == " _post_object_" ) && url.HasOption (" _post_class_" )) {
667+ TString clname = DecodeUrlOptionValue (url.GetValueFromOptions (" _post_class_" ), kTRUE );
669668 TClass *arg_cl = gROOT ->GetClass (clname, kTRUE , kTRUE );
670669 if ((arg_cl != nullptr ) && (arg_cl->GetBaseClassOffset (TObject::Class ()) == 0 ) && (post_obj == nullptr )) {
671670 post_obj = (TObject *)arg_cl->New ();
@@ -682,39 +681,61 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
682681 garbage.Add (post_obj);
683682 }
684683 }
685- sval.Form (" (%s*)0x%zx" , clname.Data (), (size_t )post_obj);
686- val = sval.Data ();
687- } else if (strcmp (val, " _post_data_" ) == 0 ) {
684+ if (!post_obj)
685+ sval = " 0" ;
686+ else
687+ sval.Form (" (%s*)0x%zx" , clname.Data (), (size_t )post_obj);
688+ } else if (sval == " _post_data_" )
688689 sval.Form (" (void*)0x%zx" , (size_t )fCurrentArg ->GetPostData ());
689- val = sval.Data ();
690- } else if (strcmp (val, " _post_length_" ) == 0 ) {
690+ else if (sval == " _post_length_" )
691691 sval.Form (" %ld" , (long )fCurrentArg ->GetPostDataLength ());
692- val = sval.Data ();
693- }
694- }
692+ else
693+ sanitize_numeric = kTRUE ;
694+ } else
695+ sanitize_numeric = kTRUE ;
695696
696- if (!val )
697- val = arg->GetDefault ();
697+ if (sval. IsNull () && arg-> GetDefault () )
698+ sval = arg->GetDefault ();
698699
699700 if (debug)
700- debug->append (TString::Format (" Argument:%s Type:%s Value:%s \n " , arg->GetName (), arg->GetFullTypeName (),
701- val ? val : " <missed>" )
702- .Data ());
703- if (!val)
704- return debug != nullptr ;
701+ debug->append (
702+ TString::Format (" Argument:%s Type:%s Value:%s \n " , arg->GetName (), arg->GetFullTypeName (), sval.Data ())
703+ .Data ());
705704
706705 if (call_args.Length () > 0 )
707706 call_args += " , " ;
708707
709- if ((strcmp (arg->GetFullTypeName (), " const char*" ) == 0 ) || (strcmp (arg->GetFullTypeName (), " Option_t*" ) == 0 )) {
710- int len = strlen (val);
711- if ((strlen (val) < 2 ) || (*val != ' \" ' ) || (val[len - 1 ] != ' \" ' ))
712- call_args.Append (TString::Format (" \" %s\" " , val));
713- else
714- call_args.Append (val);
708+ Bool_t isstr = (strcmp (arg->GetFullTypeName (), " const char*" ) == 0 ) ||
709+ (strcmp (arg->GetFullTypeName (), " Option_t*" ) == 0 ) ||
710+ (strcmp (arg->GetFullTypeName (), " string" ) == 0 );
711+
712+ if (isstr) {
713+ // check that quotes provided for the string argument
714+ // all special characters were escaped before
715+ if (sval.IsNull ())
716+ sval = " \"\" " ;
717+ else {
718+ if (sval[0 ] != ' "' )
719+ sval.Prepend (" \" " );
720+ if (sval[sval.Length () - 1 ] != ' "' )
721+ sval.Append (" \" " );
722+ }
715723 } else {
716- call_args.Append (val);
724+ // for numeric types keep only numeric and alphabetic characters
725+ // exclude others - especially remove all escape characters
726+ if (sanitize_numeric) {
727+ TString sanitized;
728+ for (Size_t i = 0 ; i < sval.Length (); ++i) {
729+ if (std::isalnum (sval[i]) || std::strchr (" .:+-" , sval[i]))
730+ sanitized.Append (sval[i]);
731+ }
732+ sval = sanitized;
733+ }
734+ if (sval.IsNull ())
735+ sval = " 0" ;
717736 }
737+
738+ call_args.Append (sval);
718739 }
719740
720741 TMethodCall *call = nullptr ;
0 commit comments