From dfc19b6079b83bb1129ec78b4426a120c0636e4d Mon Sep 17 00:00:00 2001 From: cristy Date: Fri, 17 Oct 2014 22:52:24 +0000 Subject: [PATCH] --- MagickCore/delegate-private.h | 4 + MagickCore/delegate.c | 189 +++++++++++++++++++++++++++++++++- MagickCore/utility.c | 186 --------------------------------- MagickCore/utility.h | 4 - coders/pcl.c | 4 +- coders/pdf.c | 5 +- coders/ps.c | 5 +- coders/svg.c | 4 +- coders/xps.c | 4 +- 9 files changed, 204 insertions(+), 201 deletions(-) diff --git a/MagickCore/delegate-private.h b/MagickCore/delegate-private.h index 9b4e65333..f848abb04 100644 --- a/MagickCore/delegate-private.h +++ b/MagickCore/delegate-private.h @@ -64,6 +64,10 @@ typedef struct _GhostInfo int(MagickDLLCall *)(void *,const char *,int)); } GhostInfo; +extern MagickPrivate int + ExternalDelegateCommand(const MagickBooleanType,const MagickBooleanType, + const char *,char *,ExceptionInfo *); + extern MagickPrivate MagickBooleanType DelegateComponentGenesis(void); diff --git a/MagickCore/delegate.c b/MagickCore/delegate.c index d7fa666cf..968180a9b 100644 --- a/MagickCore/delegate.c +++ b/MagickCore/delegate.c @@ -287,6 +287,193 @@ MagickPrivate void DelegateComponentTerminus(void) % % % % % % ++ E x t e r n a l D e l e g a t e C o m m a n d % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ExternalDelegateCommand() executes the specified command and waits until it +% terminates. The returned value is the exit status of the command. +% +% The format of the ExternalDelegateCommand method is: +% +% int ExternalDelegateCommand(const MagickBooleanType asynchronous, +% const MagickBooleanType verbose,const char *command, +% char *message,ExceptionInfo *exception) +% +% A description of each parameter follows: +% +% o asynchronous: a value other than 0 executes the parent program +% concurrently with the new child process. +% +% o verbose: a value other than 0 prints the executed command before it is +% invoked. +% +% o command: this string is the command to execute. +% +% o message: an option buffer to receive any message posted to stdout or +% stderr. +% +% o exception: return any errors here. +% +*/ + +static char *SanitizeDelegateCommand(const char *command) +{ + char + *sanitize_command; + + const char + *q; + + register char + *p; + + static char + whitelist[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_- " + ".@&;<>()|/\\\'\":%=~"; + + sanitize_command=AcquireString(command); + p=sanitize_command; + q=sanitize_command+strlen(sanitize_command); + for (p+=strspn(p,whitelist); p != q; p+=strspn(p,whitelist)) + *p='_'; + return(sanitize_command); +} + +MagickPrivate int ExternalDelegateCommand(const MagickBooleanType asynchronous, + const MagickBooleanType verbose,const char *command,char *message, + ExceptionInfo *exception) +{ + char + **arguments, + *sanitize_command; + + int + number_arguments, + status; + + PolicyDomain + domain; + + PolicyRights + rights; + + register ssize_t + i; + + status=(-1); + arguments=StringToArgv(command,&number_arguments); + if (arguments == (char **) NULL) + return(status); + if (*arguments[1] == '\0') + { + for (i=0; i < (ssize_t) number_arguments; i++) + arguments[i]=DestroyString(arguments[i]); + arguments=(char **) RelinquishMagickMemory(arguments); + return(-1); + } + rights=ExecutePolicyRights; + domain=DelegatePolicyDomain; + if (IsRightsAuthorized(domain,rights,arguments[1]) == MagickFalse) + { + errno=EPERM; + (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, + "NotAuthorized","`%s'",arguments[1]); + for (i=0; i < (ssize_t) number_arguments; i++) + arguments[i]=DestroyString(arguments[i]); + arguments=(char **) RelinquishMagickMemory(arguments); + return(-1); + } + if (verbose != MagickFalse) + { + (void) FormatLocaleFile(stderr,"%s\n",command); + (void) fflush(stderr); + } + sanitize_command=SanitizeDelegateCommand(command); + if (asynchronous != MagickFalse) + (void) ConcatenateMagickString(sanitize_command,"&",MaxTextExtent); + if (message != (char *) NULL) + *message='\0'; +#if defined(MAGICKCORE_POSIX_SUPPORT) +#if !defined(MAGICKCORE_HAVE_EXECVP) + status=system(sanitize_command); +#else + if ((asynchronous != MagickFalse) || + (strpbrk(sanitize_command,"&;<>|") != (char *) NULL)) + status=system(sanitize_command); + else + { + pid_t + child_pid; + + /* + Call application directly rather than from a shell. + */ + child_pid=(pid_t) fork(); + if (child_pid == (pid_t) -1) + status=system(sanitize_command); + else + if (child_pid == 0) + { + status=execvp(arguments[1],arguments+1); + _exit(1); + } + else + { + int + child_status; + + pid_t + pid; + + child_status=0; + pid=(pid_t) waitpid(child_pid,&child_status,0); + if (pid == -1) + status=(-1); + else + { + if (WIFEXITED(child_status) != 0) + status=WEXITSTATUS(child_status); + else + if (WIFSIGNALED(child_status)) + status=(-1); + } + } + } +#endif +#elif defined(MAGICKCORE_WINDOWS_SUPPORT) + status=NTSystemCommand(sanitize_command,message); +#elif defined(macintosh) + status=MACSystemCommand(sanitize_command); +#elif defined(vms) + status=system(sanitize_command); +#else +# error No suitable system() method. +#endif + if (status < 0) + { + if ((message != (char *) NULL) && (*message != '\0')) + (void) ThrowMagickException(exception,GetMagickModule(),DelegateError, + "FailedToExecuteCommand","`%s' (%s)",command,message); + else + (void) ThrowMagickException(exception,GetMagickModule(),DelegateError, + "FailedToExecuteCommand","`%s' (%d)",command,status); + } + sanitize_command=DestroyString(sanitize_command); + for (i=0; i < (ssize_t) number_arguments; i++) + arguments[i]=DestroyString(arguments[i]); + arguments=(char **) RelinquishMagickMemory(arguments); + return(status); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % % G e t D e l e g a t e C o m m a n d % % % % % @@ -1099,7 +1286,7 @@ MagickExport MagickBooleanType InvokeDelegate(ImageInfo *image_info, /* Execute delegate. */ - status=IsMagickTrue(SystemCommand(delegate_info->spawn, + status=IsMagickTrue(ExternalDelegateCommand(delegate_info->spawn, image_info->verbose,command,(char *) NULL,exception) != 0); if (IfMagickTrue(delegate_info->spawn)) { diff --git a/MagickCore/utility.c b/MagickCore/utility.c index 06795bc67..0123e269b 100644 --- a/MagickCore/utility.c +++ b/MagickCore/utility.c @@ -1883,189 +1883,3 @@ MagickPrivate MagickBooleanType ShredFile(const char *path) return(MagickFalse); return(i < (ssize_t) StringToInteger(passes) ? MagickFalse : MagickTrue); } - -/* -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% % -% % -% % -% S y s t e m C o m m a n d % -% % -% % -% % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% SystemCommand() executes the specified command and waits until it -% terminates. The returned value is the exit status of the command. -% -% The format of the SystemCommand method is: -% -% int SystemCommand(const MagickBooleanType asynchronous, -% const MagickBooleanType verbose,const char *command, -% ExceptionInfo *exception) -% -% A description of each parameter follows: -% -% o asynchronous: a value other than 0 executes the parent program -% concurrently with the new child process. -% -% o verbose: a value other than 0 prints the executed command before it is -% invoked. -% -% o command: this string is the command to execute. -% -% o output: an optional buffer to store the output from stderr/stdout. -% -% o exception: return any errors here. -% -*/ - -static char *SanitizeSystemCommand(const char *command) -{ - char - *sanitize_command; - - const char - *q; - - register char - *p; - - static char - whitelist[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_- " - ".@&;<>()|/\\\'\":%=~"; - - sanitize_command=AcquireString(command); - p=sanitize_command; - q=sanitize_command+strlen(sanitize_command); - for (p+=strspn(p,whitelist); p != q; p+=strspn(p,whitelist)) - *p='_'; - return(sanitize_command); -} - -MagickExport int SystemCommand(const MagickBooleanType asynchronous, - const MagickBooleanType verbose,const char *command,char *output, - ExceptionInfo *exception) -{ - char - **arguments, - *sanitize_command; - - int - number_arguments, - status; - - PolicyDomain - domain; - - PolicyRights - rights; - - register ssize_t - i; - - status=(-1); - arguments=StringToArgv(command,&number_arguments); - if (arguments == (char **) NULL) - return(status); - if (*arguments[1] == '\0') - { - for (i=0; i < (ssize_t) number_arguments; i++) - arguments[i]=DestroyString(arguments[i]); - arguments=(char **) RelinquishMagickMemory(arguments); - return(-1); - } - rights=ExecutePolicyRights; - domain=DelegatePolicyDomain; - if (IsRightsAuthorized(domain,rights,arguments[1]) == MagickFalse) - { - errno=EPERM; - (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, - "NotAuthorized","`%s'",arguments[1]); - for (i=0; i < (ssize_t) number_arguments; i++) - arguments[i]=DestroyString(arguments[i]); - arguments=(char **) RelinquishMagickMemory(arguments); - return(-1); - } - if (verbose != MagickFalse) - { - (void) FormatLocaleFile(stderr,"%s\n",command); - (void) fflush(stderr); - } - sanitize_command=SanitizeSystemCommand(command); - if (asynchronous != MagickFalse) - (void) ConcatenateMagickString(sanitize_command,"&",MaxTextExtent); - if (output != (char *) NULL) - *output='\0'; -#if defined(MAGICKCORE_POSIX_SUPPORT) -#if !defined(MAGICKCORE_HAVE_EXECVP) - status=system(sanitize_command); -#else - if ((asynchronous != MagickFalse) || - (strpbrk(sanitize_command,"&;<>|") != (char *) NULL)) - status=system(sanitize_command); - else - { - pid_t - child_pid; - - /* - Call application directly rather than from a shell. - */ - child_pid=(pid_t) fork(); - if (child_pid == (pid_t) -1) - status=system(sanitize_command); - else - if (child_pid == 0) - { - status=execvp(arguments[1],arguments+1); - _exit(1); - } - else - { - int - child_status; - - pid_t - pid; - - child_status=0; - pid=(pid_t) waitpid(child_pid,&child_status,0); - if (pid == -1) - status=(-1); - else - { - if (WIFEXITED(child_status) != 0) - status=WEXITSTATUS(child_status); - else - if (WIFSIGNALED(child_status)) - status=(-1); - } - } - } -#endif -#elif defined(MAGICKCORE_WINDOWS_SUPPORT) - status=NTSystemCommand(sanitize_command,output); -#elif defined(macintosh) - status=MACSystemCommand(sanitize_command); -#elif defined(vms) - status=system(sanitize_command); -#else -# error No suitable system() method. -#endif - if (status < 0) - { - if ((output != (char *) NULL) && (*output != '\0')) - (void) ThrowMagickException(exception,GetMagickModule(),DelegateError, - "FailedToExecuteCommand","`%s' (%s)",command,output); - else - (void) ThrowMagickException(exception,GetMagickModule(),DelegateError, - "FailedToExecuteCommand","`%s' (%d)",command,status); - } - sanitize_command=DestroyString(sanitize_command); - for (i=0; i < (ssize_t) number_arguments; i++) - arguments[i]=DestroyString(arguments[i]); - arguments=(char **) RelinquishMagickMemory(arguments); - return(status); -} diff --git a/MagickCore/utility.h b/MagickCore/utility.h index 33161b6f3..4dd6c2e6f 100644 --- a/MagickCore/utility.h +++ b/MagickCore/utility.h @@ -38,10 +38,6 @@ typedef enum extern MagickExport char *Base64Encode(const unsigned char *,const size_t,size_t *); -extern MagickExport int - SystemCommand(const MagickBooleanType,const MagickBooleanType,const char *, - char *,ExceptionInfo *); - extern MagickExport MagickBooleanType AcquireUniqueFilename(char *), AcquireUniqueSymbolicLink(const char *,char *), diff --git a/coders/pcl.c b/coders/pcl.c index f3deec786..4b94198f4 100644 --- a/coders/pcl.c +++ b/coders/pcl.c @@ -362,8 +362,8 @@ static Image *ReadPCLImage(const ImageInfo *image_info,ExceptionInfo *exception) read_info->antialias != MagickFalse ? 4 : 1, read_info->antialias != MagickFalse ? 4 : 1,density,options, read_info->filename,input_filename); - status=SystemCommand(MagickFalse,read_info->verbose,command,(char *) NULL, - exception) != 0 ? MagickTrue : MagickFalse; + status=ExternalDelegateCommand(MagickFalse,read_info->verbose,command, + (char *) NULL,exception) != 0 ? MagickTrue : MagickFalse; image=ReadImage(read_info,exception); (void) RelinquishUniqueFileResource(read_info->filename); (void) RelinquishUniqueFileResource(input_filename); diff --git a/coders/pdf.c b/coders/pdf.c index c75489e63..cb0931bf5 100644 --- a/coders/pdf.c +++ b/coders/pdf.c @@ -173,7 +173,8 @@ static MagickBooleanType InvokePDFDelegate(const MagickBooleanType verbose, #define ExecuteGhostscriptCommand(command,status) \ { \ - status=SystemCommand(MagickFalse,verbose,command,output,exception); \ + status=SystemCommandWidthOutput(MagickFalse,verbose,command,output, \ + exception); \ if (status == 0) \ return(MagickTrue); \ if (status < 0) \ @@ -273,7 +274,7 @@ static MagickBooleanType InvokePDFDelegate(const MagickBooleanType verbose, errors=DestroyString(errors); return(MagickTrue); #else - status=SystemCommand(MagickFalse,verbose,command,output,exception); + status=ExternalDelegateCommand(MagickFalse,verbose,command,output,exception); return(status == 0 ? MagickTrue : MagickFalse); #endif } diff --git a/coders/ps.c b/coders/ps.c index 529e2b7a6..2f532bd13 100644 --- a/coders/ps.c +++ b/coders/ps.c @@ -163,7 +163,8 @@ static MagickBooleanType InvokePostscriptDelegate( #define ExecuteGhostscriptCommand(command,status) \ { \ - status=SystemCommand(MagickFalse,verbose,command,output,exception); \ + status=SystemCommandWidthOutput(MagickFalse,verbose,command,output, \ + exception); \ if (status == 0) \ return(MagickTrue); \ if (status < 0) \ @@ -263,7 +264,7 @@ static MagickBooleanType InvokePostscriptDelegate( errors=DestroyString(errors); return(MagickTrue); #else - status=SystemCommand(MagickFalse,verbose,command,output,exception); + status=ExternalDelegateCommand(MagickFalse,verbose,command,output,exception); return(status == 0 ? MagickTrue : MagickFalse); #endif } diff --git a/coders/svg.c b/coders/svg.c index 2684793af..46b7eafcf 100644 --- a/coders/svg.c +++ b/coders/svg.c @@ -2844,8 +2844,8 @@ static Image *ReadSVGImage(const ImageInfo *image_info,ExceptionInfo *exception) (void) FormatLocaleString(command,MaxTextExtent, GetDelegateCommands(delegate_info),image->filename,filename,density, background,opacity,unique); - status=SystemCommand(MagickFalse,image_info->verbose,command, - (char *) NULL,exception); + status=ExternalDelegateCommand(MagickFalse,image_info->verbose, + command,(char *) NULL,exception); (void) RelinquishUniqueFileResource(unique); if (status == 0) { diff --git a/coders/xps.c b/coders/xps.c index 846dfb9ac..90b4a01c2 100644 --- a/coders/xps.c +++ b/coders/xps.c @@ -315,8 +315,8 @@ static Image *ReadXPSImage(const ImageInfo *image_info,ExceptionInfo *exception) read_info->antialias != MagickFalse ? 4 : 1, read_info->antialias != MagickFalse ? 4 : 1,density,options, read_info->filename,input_filename); - status=SystemCommand(MagickFalse,read_info->verbose,command,(char *) NULL, - exception) != 0 ? MagickTrue : MagickFalse; + status=ExternalDelegateCommand(MagickFalse,read_info->verbose,command, + (char *) NULL,exception) != 0 ? MagickTrue : MagickFalse; image=ReadImage(read_info,exception); (void) RelinquishUniqueFileResource(read_info->filename); (void) RelinquishUniqueFileResource(input_filename); -- 2.50.1