]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/stream.c
https://github.com/ImageMagick/ImageMagick/issues/1279
[imagemagick] / MagickCore / stream.c
index 009d10a267fd4bc1708b1507c4d257a3fcfc0f5e..b55f95900a3168b0e808805961158582d0464edb 100644 (file)
 %                                 March 2000                                  %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
 %  obtain a copy of the License at                                            %
 %                                                                             %
-%    http://www.imagemagick.org/script/license.php                            %
+%    https://www.imagemagick.org/script/license.php                           %
 %                                                                             %
 %  Unless required by applicable law or agreed to in writing, software        %
 %  distributed under the License is distributed on an "AS IS" BASIS,          %
@@ -55,6 +55,7 @@
 #include "MagickCore/memory-private.h"
 #include "MagickCore/pixel.h"
 #include "MagickCore/pixel-accessor.h"
+#include "MagickCore/policy.h"
 #include "MagickCore/quantum.h"
 #include "MagickCore/quantum-private.h"
 #include "MagickCore/semaphore.h"
@@ -127,6 +128,9 @@ static Quantum
 }
 #endif
 \f
+static ssize_t
+  cache_anonymous_memory = (-1);
+\f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -158,10 +162,8 @@ MagickExport StreamInfo *AcquireStreamInfo(const ImageInfo *image_info,
   StreamInfo
     *stream_info;
 
-  stream_info=(StreamInfo *) AcquireMagickMemory(sizeof(*stream_info));
-  if (stream_info == (StreamInfo *) NULL)
-    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
-  (void) ResetMagickMemory(stream_info,0,sizeof(*stream_info));
+  stream_info=(StreamInfo *) AcquireCriticalMemory(sizeof(*stream_info));
+  (void) memset(stream_info,0,sizeof(*stream_info));
   stream_info->pixels=(unsigned char *) MagickAssumeAligned(
     AcquireAlignedMemory(1,sizeof(*stream_info->pixels)));
   if (stream_info->pixels == (unsigned char *) NULL)
@@ -464,7 +466,7 @@ static MagickBooleanType GetOneAuthenticPixelFromStream(Image *image,
     }
   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
   {
-    PixelChannel channel=GetPixelChannelChannel(image,i);
+    PixelChannel channel = GetPixelChannelChannel(image,i);
     pixel[channel]=p[i];
   }
   return(MagickTrue);
@@ -528,7 +530,7 @@ static MagickBooleanType GetOneVirtualPixelFromStream(const Image *image,
     }
   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
   {
-    PixelChannel channel=GetPixelChannelChannel(image,i);
+    PixelChannel channel = GetPixelChannelChannel(image,i);
     pixel[channel]=p[i];
   }
   return(MagickTrue);
@@ -568,14 +570,14 @@ MagickPrivate const void *GetStreamInfoClientData(StreamInfo *stream_info)
 %                                                                             %
 %                                                                             %
 %                                                                             %
-+   G e t  V i r t u a l P i x e l s F r o m S t r e a m                      %
++   G e t V i r t u a l P i x e l s F r o m S t r e a m                       %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  GetVirtualPixelsStream() returns the pixels associated with the last
-%  call to QueueAuthenticPixelsStream() or GetVirtualPixelStream().
+%  GetVirtualPixelsStream() returns the pixels associated with the last call to
+%  QueueAuthenticPixelsStream() or GetVirtualPixelStream().
 %
 %  The format of the GetVirtualPixelsStream() method is:
 %
@@ -682,15 +684,43 @@ static inline MagickBooleanType AcquireStreamPixels(CacheInfo *cache_info,
 {
   if (cache_info->length != (MagickSizeType) ((size_t) cache_info->length))
     return(MagickFalse);
-  cache_info->mapped=MagickFalse;
-  cache_info->pixels=(Quantum *) AcquireAlignedMemory(1,(size_t)
-    cache_info->length);
-  if (cache_info->pixels == (Quantum *) NULL)
+  if (cache_anonymous_memory < 0)
     {
-      cache_info->mapped=MagickTrue;
-      cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(size_t)
-        cache_info->length);
+      char
+        *value;
+
+      /*
+        Does the security policy require anonymous mapping for pixel cache?
+      */
+      cache_anonymous_memory=0;
+      value=GetPolicyValue("pixel-cache-memory");
+      if (value == (char *) NULL)
+        value=GetPolicyValue("cache:memory-map");
+      if (LocaleCompare(value,"anonymous") == 0)
+        {
+#if defined(MAGICKCORE_HAVE_MMAP) && defined(MAP_ANONYMOUS)
+          cache_anonymous_memory=1;
+#else
+          (void) ThrowMagickException(exception,GetMagickModule(),
+            MissingDelegateError,"DelegateLibrarySupportNotBuiltIn",
+            "'%s' (policy requires anonymous memory mapping)",
+            cache_info->filename);
+#endif
+        }
+      value=DestroyString(value);
     }
+   if (cache_anonymous_memory <= 0)
+     {
+       cache_info->mapped=MagickFalse;
+       cache_info->pixels=(Quantum *) MagickAssumeAligned(
+         AcquireAlignedMemory(1,(size_t) cache_info->length));
+     }
+   else
+     {
+       cache_info->mapped=MagickTrue;
+       cache_info->pixels=(Quantum *) MapBlob(-1,IOMode,0,(size_t)
+         cache_info->length);
+     }
   if (cache_info->pixels == (Quantum *) NULL)
     {
       (void) ThrowMagickException(exception,GetMagickModule(),
@@ -744,7 +774,7 @@ static const Quantum *GetVirtualPixelStream(const Image *image,
   number_pixels=(MagickSizeType) columns*rows;
   length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
   if (cache_info->number_channels == 0)
-    length=number_pixels*sizeof(Quantum);
+    length=(size_t) number_pixels*sizeof(Quantum);
   if (cache_info->metacontent_extent != 0)
     length+=number_pixels*cache_info->metacontent_extent;
   if (cache_info->pixels == (Quantum *) NULL)
@@ -909,7 +939,7 @@ static Quantum *QueueAuthenticPixelsStream(Image *image,const ssize_t x,
   number_pixels=(MagickSizeType) columns*rows;
   length=(size_t) number_pixels*cache_info->number_channels*sizeof(Quantum);
   if (cache_info->number_channels == 0)
-    length=number_pixels*sizeof(Quantum);
+    length=(size_t) number_pixels*sizeof(Quantum);
   if (cache_info->metacontent_extent != 0)
     length+=number_pixels*cache_info->metacontent_extent;
   if (cache_info->pixels == (Quantum *) NULL)
@@ -1012,7 +1042,10 @@ MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
   read_info->stream=stream;
   image=ReadImage(read_info,exception);
   if (image != (Image *) NULL)
-    (void) SyncImagePixelCache(image,exception);
+    {
+      InitializePixelChannelMap(image);
+      ResetPixelCacheChannels(image);
+    }
   read_info=DestroyImageInfo(read_info);
   return(image);
 }
@@ -1022,6 +1055,29 @@ MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
 %                                                                             %
 %                                                                             %
 %                                                                             %
++   R e s e t S t r e a m A n o n y m o u s M e m o r y                       %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  ResetStreamAnonymousMemory() resets the anonymous_memory value.
+%
+%  The format of the ResetStreamAnonymousMemory method is:
+%
+%      void ResetStreamAnonymousMemory(void)
+%
+*/
+MagickPrivate void ResetStreamAnonymousMemory(void)
+{
+  cache_anonymous_memory=0;
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 +   S e t S t r e a m I n f o C l i e n t D a t a                             %
 %                                                                             %
 %                                                                             %
@@ -1195,7 +1251,7 @@ static size_t WriteStreamImage(const Image *image,const void *pixels,
       stream_info->pixels=(unsigned char *) AcquireAlignedMemory(1,length);
       if (stream_info->pixels == (unsigned char *) NULL)
         return(0);
-      (void) ResetMagickMemory(stream_info->pixels,0,length);
+      (void) memset(stream_info->pixels,0,length);
       stream_info->image=image;
       write_info=CloneImageInfo(stream_info->image_info);
       (void) SetImageInfo(write_info,1,stream_info->exception);
@@ -1257,6 +1313,11 @@ MagickExport Image *StreamImage(const ImageInfo *image_info,
   read_info=CloneImageInfo(image_info);
   stream_info->image_info=image_info;
   stream_info->quantum_info=AcquireQuantumInfo(image_info,(Image *) NULL);
+  if (stream_info->quantum_info == (QuantumInfo *) NULL)
+    {
+      read_info=DestroyImageInfo(read_info);
+      return((Image *) NULL);
+    }
   stream_info->exception=exception;
   read_info->client_data=(void *) stream_info;
   image=ReadStream(read_info,&WriteStreamImage,exception);
@@ -1330,6 +1391,7 @@ static MagickBooleanType StreamImagePixels(const StreamInfo *stream_info,
         ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
       return(MagickFalse);
     }
+  (void) memset(quantum_map,0,length*sizeof(*quantum_map));
   for (i=0; i < (ssize_t) length; i++)
   {
     switch (stream_info->map[i])