@@ -511,6 +511,42 @@ Bool_t TRootSnifferFull::ProduceXml(const std::string &path, const std::string &
511511 return !res.empty ();
512512}
513513
514+ // //////////////////////////////////////////////////////////////////////////////
515+ // / Verify argument value
516+ // / Remove special symbols, escape quotes
517+ // / If not string - only digits, literals, "+", "-", "." are allowed
518+
519+ TString TRootSnifferFull::SanitizeArgument (Bool_t isstr, const char *value, Bool_t onlyquotes)
520+ {
521+ Int_t beg = 0 , end = strlen (value);
522+ if (end > 0 && isstr && value[beg] == ' \" ' )
523+ beg++;
524+ if (end > 0 && isstr && value[end-1 ] == ' \" ' )
525+ end--;
526+ TString sanitized;
527+ if (isstr)
528+ sanitized.Append (" \" " ); // string start with quotes
529+ for (Int_t n = beg; n < end; ++n) {
530+ Char_t c = value[n];
531+ if (!isstr && !onlyquotes) {
532+ // for numeric types make very strict check
533+ if (std::isalnum (c) || std::strchr (" .:+-" , c))
534+ sanitized.Append (c);
535+ } else if ((c == ' \" ' ) || (c == ' \\ ' )) {
536+ // escape quotes inside string
537+ sanitized.Append (' \\ ' );
538+ sanitized.Append (c);
539+ } else if (!std::iscntrl (c)) {
540+ // exclude special chars
541+ sanitized.Append (c);
542+ }
543+ }
544+ if (isstr)
545+ sanitized.Append (' \" ' ); // string end with quotes
546+ return sanitized;
547+ }
548+
549+
514550// //////////////////////////////////////////////////////////////////////////////
515551// / Execute command for specified object
516552// /
@@ -636,6 +672,10 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
636672 val = sval.Data ();
637673 }
638674
675+ // only value provided from outside should be sanitized
676+ // default argument value or internal pointer will not
677+ Bool_t sanitize = kFALSE ;
678+
639679 if ((val != nullptr ) && (strcmp (val, " _this_" ) == 0 )) {
640680 // special case - object itself is used as argument
641681 sval.Form (" (%s*)0x%zx" , obj_cl->GetName (), (size_t )obj_ptr);
@@ -690,7 +730,11 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
690730 } else if (strcmp (val, " _post_length_" ) == 0 ) {
691731 sval.Form (" %ld" , (long )fCurrentArg ->GetPostDataLength ());
692732 val = sval.Data ();
733+ } else {
734+ sanitize = kTRUE ;
693735 }
736+ } else {
737+ sanitize = val != nullptr ;
694738 }
695739
696740 if (!val)
@@ -706,15 +750,11 @@ Bool_t TRootSnifferFull::ProduceExe(const std::string &path, const std::string &
706750 if (call_args.Length () > 0 )
707751 call_args += " , " ;
708752
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);
715- } else {
716- call_args.Append (val);
717- }
753+ Bool_t isstr = (strcmp (arg->GetFullTypeName (), " const char*" ) == 0 ) ||
754+ (strcmp (arg->GetFullTypeName (), " Option_t*" ) == 0 ) ||
755+ (strcmp (arg->GetFullTypeName (), " string" ) == 0 );
756+
757+ call_args.Append (SanitizeArgument (isstr, val, !sanitize));
718758 }
719759
720760 TMethodCall *call = nullptr ;
0 commit comments