From cec51c85fa6092c50db2be5e4910ed47d9aebc32 Mon Sep 17 00:00:00 2001 From: Dirk Lemstra Date: Fri, 1 Jan 2021 15:00:17 +0100 Subject: Fixed possible deadlock when the process is waiting for ImageMagick to read the console output. --- MagickCore/nt-base.c | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 8 deletions(-) (limited to 'MagickCore/nt-base.c') diff --git a/MagickCore/nt-base.c b/MagickCore/nt-base.c index 79b2b6baa..31b625780 100644 --- a/MagickCore/nt-base.c +++ b/MagickCore/nt-base.c @@ -42,6 +42,7 @@ #if defined(MAGICKCORE_WINDOWS_SUPPORT) #include "MagickCore/client.h" #include "MagickCore/exception-private.h" +#include "MagickCore/image-private.h" #include "MagickCore/locale_.h" #include "MagickCore/log.h" #include "MagickCore/magick.h" @@ -2301,9 +2302,7 @@ MagickPrivate int NTSystemCommand(const char *command,char *output) local_command[MagickPathExtent]; DWORD - bytes_read, - child_status, - size; + child_status; int status; @@ -2321,6 +2320,9 @@ MagickPrivate int NTSystemCommand(const char *command,char *output) SECURITY_ATTRIBUTES sa; + size_t + output_offset; + STARTUPINFO startup_info; @@ -2376,9 +2378,47 @@ MagickPrivate int NTSystemCommand(const char *command,char *output) CleanupOutputHandles; return(-1); } + if (output != (char *) NULL) + *output='\0'; if (asynchronous != MagickFalse) return(status == 0); - status=WaitForSingleObject(process_info.hProcess,INFINITE); + output_offset=0; + status=STATUS_TIMEOUT; + while (status == STATUS_TIMEOUT) + { + DWORD + size; + + status=WaitForSingleObject(process_info.hProcess,1000); + size=0; + if (read_output != (HANDLE) NULL) + if (!PeekNamedPipe(read_output,NULL,0,NULL,&size,NULL)) + break; + while (size > 0) + { + char + buffer[MagickPathExtent]; + + DWORD + bytes_read; + + if (ReadFile(read_output,buffer,sizeof(buffer)-1,&bytes_read,NULL)) + { + size_t + count; + + count=MagickMin(MagickPathExtent-1-output_offset,bytes_read); + if (count > 0) + { + CopyMagickString(output+output_offset,buffer,count); + output[count]='\0'; + output_offset=count; + } + } + if (!PeekNamedPipe(read_output,NULL,0,NULL,&size,NULL)) + break; + } + } if (status != WAIT_OBJECT_0) { CopyLastError; @@ -2394,10 +2434,6 @@ MagickPrivate int NTSystemCommand(const char *command,char *output) } CloseHandle(process_info.hProcess); CloseHandle(process_info.hThread); - if (read_output != (HANDLE) NULL) - if (PeekNamedPipe(read_output,(LPVOID) NULL,0,(LPDWORD) NULL,&size,(LPDWORD) NULL)) - if ((size > 0) && (ReadFile(read_output,output,MagickPathExtent-1,&bytes_read,NULL))) - output[bytes_read]='\0'; CleanupOutputHandles; return((int) child_status); } -- cgit v1.2.3