Package: imagemagick
Version: 6:6.2.4.5-0.5
Severity: normal
Tags: patch

Moi Ryuichi!

I intend to upload revision 6:6.2.4.5-0.6 to fix the oustanding bugs
#344997, #345238, #345595, #345876 and #347486. Most of them are
security-related and release-critical. I didn't want to hide the full
diff of the NMU in one of those bug logs. Hopefully this dummy bug
provides a more prominent place for interested folks to pick it up.
Split patches have been filed to most of the bugs above. I'm attaching
the full diff to the previous NMU 6:6.2.4.5-0.5 by Adam Conrad.

Regards,

Daniel.

diff -u imagemagick-6.2.4.5/magick/blob.c imagemagick-6.2.4.5/magick/blob.c
--- imagemagick-6.2.4.5/magick/blob.c
+++ imagemagick-6.2.4.5/magick/blob.c
@@ -2120,25 +2120,8 @@
       /*
         Form filename for multi-part images.
       */
-      (void) CopyMagickString(filename,image->filename,MaxTextExtent);
-      for (p=strchr(filename,'%'); p != (char *) NULL; p=strchr(p+1,'%'))
-      {
-        char
-          *q;
-
-        q=p+1;
-        if (*q == '0')
-          (void) strtol(q,&q,10);
-        if ((*q == '%') || (*q == 'd') || (*q == 'o') || (*q == 'x'))
-          {
-            char
-              format[MaxTextExtent];
-
-            (void) CopyMagickString(format,p,MaxTextExtent);
-            (void) FormatMagickString(p,MaxTextExtent,format,image->scene);
-            break;
-          }
-      }
+      (void) FormatMagickStringNumeric(filename,MaxTextExtent,image->filename,
+        image->scene);
       if (image_info->adjoin == MagickFalse)
         if ((image->previous != (Image *) NULL) ||
             (GetNextImageInList(image) != (Image *) NULL))
diff -u imagemagick-6.2.4.5/debian/rules imagemagick-6.2.4.5/debian/rules
--- imagemagick-6.2.4.5/debian/rules
+++ imagemagick-6.2.4.5/debian/rules
@@ -24,7 +24,7 @@
        --prefix=/usr \
        --mandir=\$${prefix}/share/man \
        --infodir=\$${prefix}/share/info \
-       --with-gs-font-dir=/usr/share/fonts/type1/gsfonts\
+       --with-gs-font-dir=/usr/share/fonts/type1/gsfonts \
        --with-magick-plus-plus \
        --enable-shared \
        --enable-lzw \
diff -u imagemagick-6.2.4.5/debian/changelog 
imagemagick-6.2.4.5/debian/changelog
--- imagemagick-6.2.4.5/debian/changelog
+++ imagemagick-6.2.4.5/debian/changelog
@@ -1,3 +1,29 @@
+imagemagick (6:6.2.4.5-0.6) unstable; urgency=high
+
+  * Non-maintainer upload.
+  * magick/display.c: In DisplayImageCommand(), expand command line before
+    allocating ressources based on argc. Patch and analysis thanks to
+    Eero Häkkinen. Closes: #345595
+  * magick/{animate.c,blob.c,display.c,image.c,log.c,montage.c,string.c,
+    string_.h}: Implement new utility function FormatMagickStringNumeric()
+    to securely expand a user-supplied format string with a single numeric
+    argument. Adjust code to use this function where appropriate.
+    (CVE-2006-0082) Closes: #345876
+  * coders/pdf.c,coders/ps.c,magick/delegate.c,magick/delegate.h,
+    magick/methods.h: Do not call external delegates with user-supplied
+    filename, but with securely named symlinks only to prevent shell command
+    injection (CVE-2005-4601). Closes: #345238
+  * debian/rules: Make sure to include trailing spaces in multi-line
+    commands to keep recent make happy. Cures problems with ghostscript
+    font path. Fix thanks to Jeff Lessem. Closes: #347486
+  * debian/imagemagick.mime: Rather than autodetect the type of an image,
+    derive it from the mime type. As a side effect, this change allows to
+    use arbitrary filenames with the 'see' command, even if they have
+    special meaning to imagemagick internally. Also clean up some typos
+    and superfluous entries once we're at it. Closes: #344997
+
+ -- Daniel Kobras <[EMAIL PROTECTED]>  Tue, 17 Jan 2006 18:33:58 +0100
+
 imagemagick (6:6.2.4.5-0.5) unstable; urgency=low
 
   * Another NMU to complete the installability fixes from 6:6.2.4.5-0.4.
diff -u imagemagick-6.2.4.5/debian/imagemagick.mime 
imagemagick-6.2.4.5/debian/imagemagick.mime
--- imagemagick-6.2.4.5/debian/imagemagick.mime
+++ imagemagick-6.2.4.5/debian/imagemagick.mime
@@ -1,45 +1,42 @@
-image/avs; display '%s'; test=test -n "$DISPLAY"
-image/bie; display '%s'; test=test -n "$DISPLAY"
-image/x-ms-bmp; display '%s'; test=test -n "$DISPLAY"
-image/cmyk; display '%s'; test=test -n "$DISPLAY"
-image/dcx; display '%s'; test=test -n "$DISPLAY"
-image/eps; display '%s'; test=test -n "$DISPLAY"
-image/fax; display '%s'; test=test -n "$DISPLAY"
-image/fits; display '%s'; test=test -n "$DISPLAY"
-image/gif; display '%s'; test=test -n "$DISPLAY"
-image/gray; display '%s'; test=test -n "$DISPLAY"
-image/gradation; display '%s'; test=test -n "$DISPLAY"
-image/hdf; display '%s'; test=test -n "$DISPLAY"
-image/jpeg; display '%s'; test=test -n "$DISPLAY"
-image/pjpeg; display '%s'; test=test -n "$DISPLAY"
-image/map; display '%s'; test=test -n "$DISPLAY"
-image/miff; display '%s'; test=test -n "$DISPLAY"
-image/mono; display '%s'; test=test -n "$DISPLAY"
-image/mtv; display '%s'; test=test -n "$DISPLAY"
-image/x-portable-bitmap; display '%s'; test=test -n "$DISPLAY"
-image/pcd; display '%s'; test=test -n "$DISPLAY"
-image/pcx; display '%s'; test=test -n "$DISPLAY"
-image/pdf; display '%s'; test=test -n "$DISPLAY"
-image/x-portable-graymap; display '%s'; test=test -n "$DISPLAY"
-image/pict; display '%s'; test=test -n "$DISPLAY"
-image/png; display '%s'; test=test -n "$DISPLAY"
-image/x-portable-anymap; display '%s'; test=test -n "$DISPLAY"
-image/x-portable-pixmap; display '%s'; test=test -n "$DISPLAY"
-image/ps; display '%s'; test=test -n "$DISPLAY"
-image/rad; display '%s'; test=test -n "$DISPLAY"
-image/x-rgb; display '%s'; test=test -n "$DISPLAY"
-image/rgba; display '%s'; test=test -n "$DISPLAY"
-image/rla; display '%s'; test=test -n "$DISPLAY"
-image/rle; display '%s'; test=test -n "$DISPLAY"
-image/sgi; display '%s'; test=test -n "$DISPLAY"
-image/sun-raster; display '%s'; test=test -n "$DISPLAY"
-image/targa; display '%s'; test=test -n "$DISPLAY"
-image/tiff; display '%s'; test=test -n "$DISPLAY"
-image/uyvu; display '%s'; test=test -n "$DISPLAY"
-image/vid; display '%s'; test=test -n "$DISPLAY"
-image/viff; display '%s'; test=test -n "$DISPLAY"
-image/x-xbitmap; display '%s'; test=test -n "$DISPLAY"
-image/x-xpixmap; display '%s'; test=test -n "$DISPLAY"
-image/x-xwindowdump; display '%s'; test=test -n "$DISPLAY"
-image/x-icon; display '%s'; test=test -n "$DISPLAY"
-image/yuv; display '%s'; test=test -n "$DISPLAY"
+image/avs; display 'avs:%s'; test=test -n "$DISPLAY"
+image/bie; display 'jbig:%s'; test=test -n "$DISPLAY"
+image/x-ms-bmp; display 'bmp:%s'; test=test -n "$DISPLAY"
+image/cmyk; display 'cmyk:%s'; test=test -n "$DISPLAY"
+image/dcx; display 'dcx:%s'; test=test -n "$DISPLAY"
+image/eps; display 'eps:%s'; test=test -n "$DISPLAY"
+image/fax; display 'fax:%s'; test=test -n "$DISPLAY"
+image/fits; display 'fits:%s'; test=test -n "$DISPLAY"
+image/gif; display 'gif:%s'; test=test -n "$DISPLAY"
+image/gray; display 'gray:%s'; test=test -n "$DISPLAY"
+image/jpeg; display 'jpeg:%s'; test=test -n "$DISPLAY"
+image/pjpeg; display 'jpeg:%s'; test=test -n "$DISPLAY"
+image/miff; display 'miff:%s'; test=test -n "$DISPLAY"
+image/mono; display 'mono:%s'; test=test -n "$DISPLAY"
+image/mtv; display 'mtv:%s'; test=test -n "$DISPLAY"
+image/x-portable-bitmap; display 'pbm:%s'; test=test -n "$DISPLAY"
+image/pcd; display 'pcd:%s'; test=test -n "$DISPLAY"
+image/pcx; display 'pcx:%s'; test=test -n "$DISPLAY"
+image/pdf; display 'pdf:%s'; test=test -n "$DISPLAY"
+image/x-portable-graymap; display 'pgm:%s'; test=test -n "$DISPLAY"
+image/pict; display 'pict:%s'; test=test -n "$DISPLAY"
+image/png; display 'png:%s'; test=test -n "$DISPLAY"
+image/x-portable-anymap; display 'pnm:%s'; test=test -n "$DISPLAY"
+image/x-portable-pixmap; display 'ppm:%s'; test=test -n "$DISPLAY"
+image/ps; display 'ps:%s'; test=test -n "$DISPLAY"
+image/rad; display 'rad:%s'; test=test -n "$DISPLAY"
+image/x-rgb; display 'rgb:%s'; test=test -n "$DISPLAY"
+image/rgba; display 'rgba:%s'; test=test -n "$DISPLAY"
+image/rla; display 'rla:%s'; test=test -n "$DISPLAY"
+image/rle; display 'rle:%s'; test=test -n "$DISPLAY"
+image/sgi; display 'sgi:%s'; test=test -n "$DISPLAY"
+image/sun-raster; display 'sun:%s'; test=test -n "$DISPLAY"
+image/targa; display 'tga:%s'; test=test -n "$DISPLAY"
+image/tiff; display 'tiff:%s'; test=test -n "$DISPLAY"
+image/uyvy; display 'uyvy:%s'; test=test -n "$DISPLAY"
+image/vid; display 'vid:%s'; test=test -n "$DISPLAY"
+image/viff; display 'viff:%s'; test=test -n "$DISPLAY"
+image/x-xbitmap; display 'xbm:%s'; test=test -n "$DISPLAY"
+image/x-xpixmap; display 'xpm:%s'; test=test -n "$DISPLAY"
+image/x-xwindowdump; display 'xwd:%s'; test=test -n "$DISPLAY"
+image/x-icon; display 'icon:%s'; test=test -n "$DISPLAY"
+image/yuv; display 'yuv:%s'; test=test -n "$DISPLAY"
only in patch2:
unchanged:
--- imagemagick-6.2.4.5.orig/coders/pdf.c
+++ imagemagick-6.2.4.5/coders/pdf.c
@@ -356,6 +356,16 @@
       " -sPDFPassword=%s",read_info->authenticate);
   (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
   (void) AcquireUniqueFilename(read_info->filename);
+  if (AcquireTemporarySymlink((char *) image_info->filename,filename)
+        == MagickFalse)
+    {
+      (void) RelinquishUniqueFileResource(postscript_filename);
+      (void) RelinquishUniqueFileResource(read_info->filename);
+      (void) DestroyImageInfo(read_info);
+      ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
+        image_info->filename);
+      return((Image *) NULL);
+    }
   (void) FormatMagickString(command,MaxTextExtent,
     GetDelegateCommands(delegate_info),
     read_info->antialias != MagickFalse ? 4 : 1,
@@ -363,6 +373,8 @@
     read_info->filename,postscript_filename,image_info->filename);
   status=InvokePostscriptDelegate(read_info->verbose,command);
   image=ReadImage(read_info,exception);
+  unlink(image_info->filename);
+  (void) CopyMagickString((char *) 
image_info->filename,filename,MaxTextExtent);
   (void) RelinquishUniqueFileResource(postscript_filename);
   (void) RelinquishUniqueFileResource(read_info->filename);
   read_info=DestroyImageInfo(read_info);
only in patch2:
unchanged:
--- imagemagick-6.2.4.5.orig/coders/ps.c
+++ imagemagick-6.2.4.5/coders/ps.c
@@ -479,6 +479,16 @@
     }
   (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
   (void) AcquireUniqueFilename(read_info->filename);
+  if (AcquireTemporarySymlink((char *) image_info->filename,filename)
+        == MagickFalse)
+    {
+      (void) RelinquishUniqueFileResource(postscript_filename);
+      (void) RelinquishUniqueFileResource(read_info->filename);
+      (void) DestroyImageInfo(read_info);
+      ThrowFileException(&image->exception,FileOpenError,
+        "UnableToCreateTemporaryFile",image_info->filename);
+      return((Image *) NULL);
+    }
   (void) FormatMagickString(command,MaxTextExtent,
     GetDelegateCommands(delegate_info),
     read_info->antialias != MagickFalse ? 4 : 1,
@@ -495,6 +505,8 @@
     }
   (void) RelinquishUniqueFileResource(postscript_filename);
   (void) RelinquishUniqueFileResource(read_info->filename);
+  unlink(image_info->filename);
+  (void) CopyMagickString((char *) 
image_info->filename,filename,MaxTextExtent);
   if (image == (Image *) NULL)
     {
       /*
only in patch2:
unchanged:
--- imagemagick-6.2.4.5.orig/magick/animate.c
+++ imagemagick-6.2.4.5/magick/animate.c
@@ -604,7 +604,7 @@
               /*
                 Form filename for multi-part images.
               */
-              (void) FormatMagickString(filename,MaxTextExtent,
+              (void) FormatMagickStringNumeric(filename,MaxTextExtent,
                 image_info->filename,scene);
               if (LocaleCompare(filename,image_info->filename) == 0)
                 (void) FormatMagickString(filename,MaxTextExtent,"%s[%lu]",
only in patch2:
unchanged:
--- imagemagick-6.2.4.5.orig/magick/delegate.c
+++ imagemagick-6.2.4.5/magick/delegate.c
@@ -673,6 +673,72 @@
 %                                                                             %
 %                                                                             %
 %                                                                             %
++   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)
+%
+%  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
+    *tempname;
+
+  int
+    fd,
+    tries;
+
+  assert(linkname != (char *)NULL);
+  linkname[0]='\0';
+  linkname[MaxTextExtent-1]='\0';
+
+  for (tries=0; tries < 15; tries++)
+    {
+      tempname=tempnam(getenv("MAGICK_TMPDIR"),"magick-");
+      strncpy(linkname,tempname,MaxTextExtent-1);
+      free(tempname);
+      if (*name == '/')
+        fd=symlink(name, linkname);
+      else
+        {
+          char cname[MaxTextExtent];
+          if (!getcwd(cname,(size_t)MaxTextExtent))
+            return (MagickFalse);
+          strncat(cname,"/",MaxTextExtent-1);
+          strncat(cname,name,MaxTextExtent-1);
+          fd=symlink(cname,linkname);
+        }
+      if (fd != -1)
+        {
+          close(fd);
+          return (MagickTrue);
+        }
+    }
+  return (MagickFalse);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   I n v o k e D e l e g a t e                                               %
 %                                                                             %
 %                                                                             %
@@ -704,8 +770,11 @@
   char
     *command,
     **commands,
+    linkedname[MaxTextExtent],
+    linkedinfoname[MaxTextExtent],
     filename[MaxTextExtent];
 
+
   const DelegateInfo
     *delegate_info;
 
@@ -725,20 +794,40 @@
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+  linkedname[0]='\0';
+  linkedinfoname[0]='\0';
   temporary=(MagickBooleanType) (*image->filename == '\0');
   if (temporary != MagickFalse)
-    if (AcquireUniqueFilename(image->filename) == MagickFalse)
-      {
-        ThrowFileException(exception,FileOpenError,
-          "UnableToCreateTemporaryFile",image->filename);
-        return(MagickFalse);
-      }
+    {
+      if (AcquireUniqueFilename(image->filename) == MagickFalse)
+        {
+          ThrowFileException(exception,FileOpenError,
+            "UnableToCreateTemporaryFile",image->filename);
+          return(MagickFalse);
+        }
+    }
+  else
+    {
+      (void) CopyMagickString(linkedname,image->filename,MaxTextExtent);
+      if (AcquireTemporarySymlink(image->filename,linkedname) == MagickFalse)
+        {
+          ThrowFileException(exception,FileOpenError,
+            "UnableToCreateTemporaryFile",image->filename);
+          return(MagickFalse);
+        }
+    }
+          
   (void) CopyMagickString(filename,image->filename,MaxTextExtent);
   delegate_info=GetDelegateInfo(decode,encode,exception);
   if (delegate_info == (DelegateInfo *) NULL)
     {
       if (temporary != MagickFalse)
         (void) RelinquishUniqueFileResource(image->filename);
+      else
+        {
+           unlink(image->filename);
+           (void) CopyMagickString(image->filename,linkedname,MaxTextExtent);
+        }
       (void) ThrowMagickException(exception,GetMagickModule(),DelegateError,
         "NoTagFound","`%s'",decode ? decode : encode);
       return(MagickFalse);
@@ -749,12 +838,31 @@
         {
           if (temporary != MagickFalse)
             (void) RelinquishUniqueFileResource(image->filename);
+          else
+            {
+               unlink(image->filename);
+               (void) CopyMagickString(image->filename,linkedname,
+                 MaxTextExtent);
+            }
           ThrowFileException(exception,FileOpenError,
             "UnableToCreateTemporaryFile",image_info->filename);
           return(MagickFalse);
         }
       image_info->temporary=MagickTrue;
     }
+  else
+    {
+      (void) CopyMagickString(linkedinfoname,image_info->filename,
+        MaxTextExtent);
+      if (AcquireTemporarySymlink(image_info->filename,linkedinfoname)
+           == MagickFalse)
+        {
+          ThrowFileException(exception,FileOpenError,
+            "UnableToCreateTemporaryFile",image_info->filename);
+         return(MagickFalse);
+       }
+    }
+
   if (delegate_info->mode != 0)
     if (((decode != (const char *) NULL) &&
          (delegate_info->encode != (char *) NULL)) ||
@@ -795,6 +903,12 @@
             (void) RelinquishUniqueFileResource(image_info->zero);
             if (temporary != MagickFalse)
               (void) RelinquishUniqueFileResource(image->filename);
+           else
+              {
+                 unlink(image->filename);
+                 (void) CopyMagickString(image->filename,linkedname,
+                   MaxTextExtent);
+               }
             (void) ThrowMagickException(exception,GetMagickModule(),
               DelegateError,"DelegateFailed","`%s'",decode ? decode : encode);
             return(MagickFalse);
@@ -822,6 +936,12 @@
               (void) RelinquishUniqueFileResource(image_info->zero);
               if (temporary != MagickFalse)
                 (void) RelinquishUniqueFileResource(image->filename);
+             else
+                {
+                  unlink(image->filename);
+                 (void) CopyMagickString(image->filename,linkedname,
+                    MaxTextExtent);
+               }
               clone_info=DestroyImageInfo(clone_info);
               (void) ThrowMagickException(exception,GetMagickModule(),
                 DelegateError,"DelegateFailed","`%s'",decode ? decode : 
encode);
@@ -843,6 +963,18 @@
     {
       if (temporary != MagickFalse)
         (void) RelinquishUniqueFileResource(image->filename);
+      else
+        {
+          unlink(image->filename);
+          (void) CopyMagickString(image->filename,linkedname,
+             MaxTextExtent);
+        }
+      if (*linkedinfoname)
+        {
+          unlink(image_info->filename);
+          (void) CopyMagickString(image_info->filename,linkedinfoname,
+             MaxTextExtent);
+        }
       (void) ThrowMagickException(exception,GetMagickModule(),
         ResourceLimitError,"MemoryAllocationFailed","`%s'",
         decode ? decode : encode);
@@ -895,6 +1027,18 @@
   commands=(char **) RelinquishMagickMemory(commands);
   if (temporary != MagickFalse)
     (void) RelinquishUniqueFileResource(image->filename);
+  else
+    {
+      unlink(image->filename);
+      (void) CopyMagickString(image->filename,linkedname,
+         MaxTextExtent);
+    }
+  if (*linkedinfoname)
+    {
+      unlink(image_info->filename);
+      (void) CopyMagickString(image_info->filename,linkedinfoname,
+         MaxTextExtent);
+    }
   return((MagickBooleanType) (status == MagickFalse));
 }
 
only in patch2:
unchanged:
--- imagemagick-6.2.4.5.orig/magick/delegate.h
+++ imagemagick-6.2.4.5/magick/delegate.h
@@ -96,6 +96,9 @@
 extern MagickExport long
   GetDelegateMode(const DelegateInfo *);
 
+extern MagickExport unsigned int
+  AcquireTemporarySymlink(char *, const char *);
+
 extern MagickExport MagickBooleanType
   InvokePostscriptDelegate(const MagickBooleanType,const char *),
   InvokeDelegate(ImageInfo *,Image *,const char *,const char *,ExceptionInfo 
*),
only in patch2:
unchanged:
--- imagemagick-6.2.4.5.orig/magick/display.c
+++ imagemagick-6.2.4.5/magick/display.c
@@ -1841,10 +1841,7 @@
   image_number=0;
   last_image=0;
   last_scene=0;
-  image_marker=(unsigned long *)
-    AcquireMagickMemory((argc+1)*sizeof(*image_marker));
-  for (i=0; i <= argc; i++)
-    image_marker[i]=(unsigned long) argc;
+  image_marker=(unsigned long *) NULL;
   option=(char *) NULL;
   pend=MagickFalse;
   resource_database=(XrmDatabase) NULL;
@@ -1852,9 +1849,6 @@
   server_name=(char *) NULL;
   state=0;
   status=MagickTrue;
-  if (image_marker == (unsigned long *) NULL)
-    ThrowDisplayException(ResourceLimitError,"MemoryAllocationFailed",
-      strerror(errno));
   /*
     Check for server name specified on the command line.
   */
@@ -1863,6 +1857,13 @@
   if (status == MagickFalse)
     ThrowDisplayException(ResourceLimitError,"MemoryAllocationFailed",
       strerror(errno));
+  image_marker=(unsigned long *)
+    AcquireMagickMemory((argc+1)*sizeof(*image_marker));
+  for (i=0; i <= argc; i++)
+    image_marker[i]=(unsigned long) argc;
+  if (image_marker == (unsigned long *) NULL)
+    ThrowDisplayException(ResourceLimitError,"MemoryAllocationFailed",
+      strerror(errno));
   for (i=1; i < (long) argc; i++)
   {
     /*
@@ -1983,7 +1984,7 @@
               /*
                 Form filename for multi-part images.
               */
-              (void) FormatMagickString(filename,MaxTextExtent,
+              (void) FormatMagickStringNumeric(filename,MaxTextExtent,
                 image_info->filename,scene);
               if (LocaleCompare(filename,image_info->filename) == 0)
                 (void) FormatMagickString(filename,MaxTextExtent,"%s.%lu",
only in patch2:
unchanged:
--- imagemagick-6.2.4.5.orig/magick/image.c
+++ imagemagick-6.2.4.5/magick/image.c
@@ -2869,25 +2869,8 @@
       /*
         Rectify multi-image file support.
       */
-      (void) CopyMagickString(filename,image_info->filename,MaxTextExtent);
-      for (p=strchr(filename,'%'); 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
-              format[MaxTextExtent];
-
-            (void) CopyMagickString(format,p,MaxTextExtent);
-            (void) 
FormatMagickString(p,MaxTextExtent,format,image_info->scene);
-            break;
-          }
-      }
+      (void) FormatMagickStringNumeric(filename,MaxTextExtent,
+        image_info->filename,image_info->scene);
       if ((LocaleCompare(filename,image_info->filename) != 0) &&
           (strchr(filename,'%') == (char *) NULL))
         image_info->adjoin=MagickFalse;
only in patch2:
unchanged:
--- imagemagick-6.2.4.5.orig/magick/log.c
+++ imagemagick-6.2.4.5/magick/log.c
@@ -914,8 +914,8 @@
           char
             filename[MaxTextExtent];
 
-          (void) FormatMagickString(filename,MaxTextExtent,log_info->filename,
-            log_info->generation % log_info->generations);
+          (void) FormatMagickStringNumeric(filename,MaxTextExtent,
+            log_info->filename,log_info->generation % log_info->generations);
           log_info->file=fopen(filename,"w");
           if (log_info->file == (FILE *) NULL)
             {
only in patch2:
unchanged:
--- imagemagick-6.2.4.5.orig/magick/methods.h
+++ imagemagick-6.2.4.5/magick/methods.h
@@ -47,6 +47,7 @@
 #define AcquireSemaphoreInfo  PrependMagickMethod(AcquireSemaphoreInfo)
 #define AcquireStringInfo  PrependMagickMethod(AcquireStringInfo)
 #define AcquireString  PrependMagickMethod(AcquireString)
+#define AcquireTemporarySymlink PrependMagickMethod(AcquireTemporarySymlink)
 #define AcquireUniqueFilename  PrependMagickMethod(AcquireUniqueFilename)
 #define AcquireUniqueFileResource  
PrependMagickMethod(AcquireUniqueFileResource)
 #define AdaptiveThresholdImage  PrependMagickMethod(AdaptiveThresholdImage)
only in patch2:
unchanged:
--- imagemagick-6.2.4.5.orig/magick/montage.c
+++ imagemagick-6.2.4.5/magick/montage.c
@@ -530,7 +530,7 @@
               /*
                 Form filename for multi-part images.
               */
-              (void) FormatMagickString(filename,MaxTextExtent,
+              (void) FormatMagickStringNumeric(filename,MaxTextExtent,
                 image_info->filename,scene);
               if (LocaleCompare(filename,image_info->filename) == 0)
                 (void) FormatMagickString(filename,MaxTextExtent,"%s.%lu",
only in patch2:
unchanged:
--- imagemagick-6.2.4.5.orig/magick/string.c
+++ imagemagick-6.2.4.5/magick/string.c
@@ -960,6 +960,75 @@
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%  F o r m a t M a g i c k S t r i n g N u m e r i c                          %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  Method FormatMagickStringNumeric formats output for a single numeric
+%  argument. It takes into account that the format string given might be
+%  untrusted user input, and returns the length of the formatted string.
+%
+%  The format of the FormatMagickStringNumeric method is:
+%
+%      long FormatMagickStringNumeric(char *string,const size_t length,
+%                                     const char *format,int value)
+%
+%  A description of each parameter follows.
+%
+%   o string:  FormatMagickStringNumeric() returns the formatted string in this
+%     character buffer.
+%
+%   o length: The maximum length of the string.
+%
+%   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 long FormatMagickStringNumeric(char *string,const size_t 
length,const char *format,int value)
+{
+  char
+    *p;
+
+  (void) CopyMagickString(string, format, length);
+
+  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),length-(p-format),p,value);
+      *q=c;
+      (void) ConcatenateMagickString(string,q,length);
+      if (*(q-1) == '%')
+        p++;
+      else
+        break;
+    }
+  }
+  return (long)strlen(string);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %  F o r m a t M a g i c k S t r i n g                                        %
 %                                                                             %
 %                                                                             %
only in patch2:
unchanged:
--- imagemagick-6.2.4.5.orig/magick/string_.h
+++ imagemagick-6.2.4.5/magick/string_.h
@@ -60,6 +60,7 @@
     magick_attribute((format (printf,3,4))),
   FormatMagickStringList(char *,const size_t,const char *,va_list)
     magick_attribute((format (printf,3,0))),
+  FormatMagickStringNumeric(char *,const size_t,const char *,int),
   LocaleCompare(const char *,const char *),
   LocaleNCompare(const char *,const char *,const size_t);
 

Reply via email to