File GraphicsMagick-debian-fixed.patch of Package GraphicsMagick.7727
Index: GraphicsMagick-1.3.18/magick/delegate.c
===================================================================
--- GraphicsMagick-1.3.18.orig/magick/delegate.c
+++ GraphicsMagick-1.3.18/magick/delegate.c
@@ -539,7 +539,10 @@ MagickExport unsigned int InvokeDelegate
char
*command,
**commands,
- filename[MaxTextExtent];
+ linkedname[MaxTextExtent],
+ linkedinfoname[MaxTextExtent],
+ filename[MaxTextExtent],
+ safechars[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,-_+ /";
const DelegateInfo
*delegate_info;
@@ -559,6 +562,10 @@ MagickExport unsigned int InvokeDelegate
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
temporary_image_filename=(*image->filename == '\0');
+ linkedname[0]='\0';
+ linkedname[MaxTextExtent-1]='\0';
+ linkedinfoname[0]='\0';
+ linkedinfoname[MaxTextExtent-1]='\0';
if (temporary_image_filename)
{
/* Allocate a temporary filename if image is unnamed. */
@@ -568,12 +575,24 @@ MagickExport unsigned int InvokeDelegate
return(False);
}
}
+ else if (strspn(image->filename, safechars) != strlen(image->filename))
+ {
+ strncpy(linkedname,image->filename,MaxTextExtent-1);
+ if (!AcquireTemporarySymlink(image->filename,linkedname))
+ {
+ (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image->filename);
+ return (False);
+ }
+ }
+
(void) strlcpy(filename,image->filename,MaxTextExtent);
delegate_info=GetDelegateInfo(decode,encode,exception);
if (delegate_info == (DelegateInfo *) NULL)
{
if (temporary_image_filename)
(void) LiberateTemporaryFile(image->filename);
+ if (*linkedname)
+ strncpy(image->filename,linkedname,MaxTextExtent-1);
(void) ThrowException(exception,DelegateError,NoTagFound,
decode ? decode : encode);
return(False);
@@ -594,6 +613,18 @@ MagickExport unsigned int InvokeDelegate
}
image_info->temporary=True;
}
+ else if (strspn(image_info->filename, safechars) != strlen(image_info->filename))
+ {
+ strncpy(linkedinfoname,image_info->filename,MaxTextExtent-1);
+ if (!AcquireTemporarySymlink(image_info->filename,linkedinfoname))
+ {
+ if (temporary_image_filename)
+ LiberateTemporaryFile(image->filename);
+ (void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->filename);
+ return(False);
+ }
+ temporary_image_filename=True;
+ }
if (delegate_info->mode != 0)
if ((decode && (delegate_info->encode != (char *) NULL)) ||
@@ -617,6 +648,13 @@ MagickExport unsigned int InvokeDelegate
{
if (temporary_image_filename)
(void) LiberateTemporaryFile(image->filename);
+ if (*linkedname)
+ strncpy(image->filename,linkedname,MaxTextExtent-1);
+ if (*linkedinfoname)
+ {
+ LiberateTemporaryFile(linkedinfoname);
+ strncpy(image_info->filename,linkedinfoname,MaxTextExtent-1);
+ }
(void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->unique);
return(False);
}
@@ -625,6 +663,13 @@ MagickExport unsigned int InvokeDelegate
{
if (temporary_image_filename)
(void) LiberateTemporaryFile(image->filename);
+ if (*linkedname)
+ strncpy(image->filename,linkedname,MaxTextExtent-1);
+ if (*linkedinfoname)
+ {
+ LiberateTemporaryFile(linkedinfoname);
+ strncpy(image_info->filename,linkedinfoname,MaxTextExtent-1);
+ }
(void) LiberateTemporaryFile(image_info->unique);
(void) ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile,image_info->zero);
return(False);
@@ -638,6 +683,13 @@ MagickExport unsigned int InvokeDelegate
(void) LiberateTemporaryFile(image_info->zero);
if (temporary_image_filename)
(void) LiberateTemporaryFile(image->filename);
+ if (*linkedname)
+ strncpy(image->filename,linkedname,MaxTextExtent-1);
+ if (*linkedinfoname)
+ {
+ LiberateTemporaryFile(linkedinfoname);
+ strncpy(image_info->filename,linkedinfoname,MaxTextExtent-1);
+ }
(void) ThrowException(exception,DelegateError,DelegateFailed,
decode ? decode : encode);
return(False);
@@ -663,6 +715,13 @@ MagickExport unsigned int InvokeDelegate
(void) LiberateTemporaryFile(image_info->zero);
if (temporary_image_filename)
(void) LiberateTemporaryFile(image->filename);
+ if (*linkedname)
+ strncpy(image->filename,linkedname,MaxTextExtent-1);
+ if (*linkedinfoname)
+ {
+ LiberateTemporaryFile(linkedinfoname);
+ strncpy(image_info->filename,linkedinfoname,MaxTextExtent-1);
+ }
DestroyImageInfo(clone_info);
(void) ThrowException(exception,DelegateError,DelegateFailed,
decode ? decode : encode);
@@ -684,6 +743,13 @@ MagickExport unsigned int InvokeDelegate
{
if (temporary_image_filename)
(void) LiberateTemporaryFile(image->filename);
+ if (*linkedname)
+ strncpy(image->filename,linkedname,MaxTextExtent-1);
+ if (*linkedinfoname)
+ {
+ LiberateTemporaryFile(linkedinfoname);
+ strncpy(image_info->filename,linkedinfoname,MaxTextExtent-1);
+ }
(void) ThrowException(exception,ResourceLimitError,MemoryAllocationFailed,decode ? decode : encode);
return(False);
}
@@ -810,6 +876,13 @@ MagickExport unsigned int InvokeDelegate
error_exit:
if (temporary_image_filename)
(void) LiberateTemporaryFile(image->filename);
+ if (*linkedname)
+ strncpy(image->filename,linkedname,MaxTextExtent-1);
+ if (*linkedinfoname)
+ {
+ LiberateTemporaryFile(linkedinfoname);
+ strncpy(image_info->filename,linkedinfoname,MaxTextExtent-1);
+ }
for ( ; commands[i] != (char *) NULL; i++)
MagickFreeMemory(commands[i]);
MagickFreeMemory(commands);
Index: GraphicsMagick-1.3.18/magick/symbols.h
===================================================================
--- GraphicsMagick-1.3.18.orig/magick/symbols.h
+++ GraphicsMagick-1.3.18/magick/symbols.h
@@ -43,6 +43,7 @@
#define AcquireTemporaryFileDescriptor GmAcquireTemporaryFileDescriptor
#define AcquireTemporaryFileName GmAcquireTemporaryFileName
#define AcquireTemporaryFileStream GmAcquireTemporaryFileStream
+#define AcquireTemporarySymlink GmAcquireTemporarySymlink
#define AdaptiveThresholdImage GmAdaptiveThresholdImage
#define AddDefinition GmAddDefinition
#define AddDefinitions GmAddDefinitions
Index: GraphicsMagick-1.3.18/magick/tempfile.c
===================================================================
--- GraphicsMagick-1.3.18.orig/magick/tempfile.c
+++ GraphicsMagick-1.3.18/magick/tempfile.c
@@ -192,6 +192,93 @@ MagickExport MagickPassFail AcquireTempo
% %
% %
% %
++ A c q u i r e T e m p o r a r y S y m l i n k %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AcquireTemporarySymlink replaces the contents of the string buffer pointed
+% to by filename with the unique name of a symbolic link. True is returned
+% if a symlink waas created, or False is returned if there is a failure.
+% The allocated symlink should be recovered via the LiberateTemporaryFile()
+% function once it is no longer required.
+%
+% The format of the AcquireTemporarySymlink method is:
+%
+% unsigned int AcquireTemporarySymlink(char *linkname, const char *name,
+% ExceptionInfo *exception)
+%
+% A description of each parameter follows.
+%
+% o linkname: Specifies a pointer to an array of characters that must be
+% MaxTextExtent characters of size. The unique
+% name of the symlink is returned in this array.
+% o name: Specifies a file name the symlink should point to.
+*/
+MagickExport unsigned int AcquireTemporarySymlink(char *linkname, const char *name)
+{
+ char
+ *tempdir,
+ tempname[MaxTextExtent];
+
+ int
+ fd,
+ tries;
+
+ assert(linkname != (char *)NULL);
+ linkname[0]='\0';
+ tempname[MaxTextExtent-1]='\0';
+
+ tempdir=getenv("MAGICK_TMPDIR");
+#if defined(POSIX)
+ if (!tempdir)
+ tempdir=getenv("TMPDIR");
+#endif /* POSIX */
+#if defined(WIN32)
+ if (!tempdir)
+ tempdir=getenv("TMP");
+ if (!tempdir)
+ tempdir=getenv("TEMP");
+#endif /* WIN32 */
+#if defined(P_tmpdir)
+ if (!tempdir)
+ tempdir=P_tmpdir;
+#endif
+
+ for (tries=0; tries < 15; tries++)
+ {
+ strncpy(tempname,"gmXXXXXX",MaxTextExtent-1);
+ ComposeTemporaryFileName(tempname);
+ strncpy(linkname,tempdir,MaxTextExtent-1);
+ if (tempdir[strlen(tempdir)-1] != DirectorySeparator[0])
+ strncat(linkname,DirectorySeparator,MaxTextExtent-1);
+ strncat(linkname,tempname,MaxTextExtent-1);
+ if (*name == '/')
+ fd=symlink(name, linkname);
+ else
+ {
+ char cname[MaxTextExtent];
+ if (!getcwd(cname,(size_t)MaxTextExtent))
+ return (False);
+ strncat(cname,DirectorySeparator,MaxTextExtent-1);
+ strncat(cname,name,MaxTextExtent-1);
+ fd=symlink(cname,linkname);
+ }
+ if (fd != -1)
+ {
+ AddTemporaryFileToList(linkname);
+ return (True);
+ }
+ }
+ return (False);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+ A c q u i r e T e m p o r a r y F i l e D e s c r i p t o r %
% %
% %
Index: GraphicsMagick-1.3.18/magick/tempfile.h
===================================================================
--- GraphicsMagick-1.3.18.orig/magick/tempfile.h
+++ GraphicsMagick-1.3.18/magick/tempfile.h
@@ -24,6 +24,7 @@ typedef enum
MagickExport MagickPassFail
AcquireTemporaryFileName(char *filename),
+ AcquireTemporarySymlink(char *linkname, const char *name),
LiberateTemporaryFile(char *filename);
MagickExport int
Index: GraphicsMagick-1.3.18/magick/utility.c
===================================================================
--- GraphicsMagick-1.3.18.orig/magick/utility.c
+++ GraphicsMagick-1.3.18/magick/utility.c
@@ -1253,6 +1253,72 @@ MagickExport void FormatString(char *str
% %
% %
% %
+% F o r m a t S t r i n g N u m e r i c %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Method FormatStringNumeric formats output for a single numeric argument.
+% It takes into account that the format string given might be untrusted
+% user input, and returns a pointer to the formatted string.
+%
+% The format of the FormatStringNumeric method is:
+%
+% char * FormatStringNumeric(char *string,const char *format,int value)
+%
+% A description of each parameter follows.
+%
+% o format: A string describing the format to use to write the numeric
+% argument. Only the first numeric format identifier is replaced.
+%
+% o value: Numeric value to substitute into format string.
+%
+%
+*/
+MagickExport char *FormatStringNumeric(const char *format,int value)
+{
+ char
+ *p,
+ *string;
+
+ string = NULL;
+
+ (void) CloneString(&string, format);
+
+ for (p=strchr(format,'%'); p != (char *) NULL; p=strchr(p+1,'%'))
+ {
+ char
+ *q;
+
+ q=(char *) p+1;
+ if (*q == '0')
+ (void) strtol(q,&q,10);
+ if ((*q == '%') || (*q == 'd') || (*q == 'o') || (*q == 'x'))
+ {
+ char
+ c;
+
+ q++;
+ c=*q;
+ *q='\0';
+ (void) snprintf(string+(p-format),MaxTextExtent-(p-format),p,value);
+ *q=c;
+ (void) ConcatenateString(&string,q);
+ if (*(q-1) == '%')
+ p++;
+ else
+ break;
+ }
+ }
+ return string;
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% G e t E x e c u t i o n P a t h %
% %
% %
Index: GraphicsMagick-1.3.18/magick/utility.h
===================================================================
--- GraphicsMagick-1.3.18.orig/magick/utility.h
+++ GraphicsMagick-1.3.18/magick/utility.h
@@ -72,6 +72,7 @@ extern MagickExport char
*AllocateString(const char *),
*Base64Encode(const unsigned char *,const size_t,size_t *),
*EscapeString(const char *,const char),
+ *FormatStringNumeric(const char *,int),
*GetPageGeometry(const char *),
**ListFiles(const char *,const char *,long *),
**StringToArgv(const char *,int *),