Commit 20dcf6d0a for imagemagick.org
commit 20dcf6d0aae2ca1d8a263f5855808d6ff7f0b1e3
Author: Cristy <urban-warrior@imagemagick.org>
Date: Sat Jul 18 12:06:01 2026 -0400
safe read/write
diff --git a/MagickCore/blob.c b/MagickCore/blob.c
index f8b340738..346f4b0f2 100644
--- a/MagickCore/blob.c
+++ b/MagickCore/blob.c
@@ -395,14 +395,10 @@ MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
}
for (i=0; i < length; i+=(size_t) count)
{
- count=write(file,(const char *) blob+i,MagickMin(length-i,(size_t)
+ count=MagickWrite(file,(const char *) blob+i,MagickMin(length-i,(size_t)
MagickMaxBufferExtent));
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
}
file=close_utf8(file);
if ((file == -1) || (i < length))
@@ -1502,13 +1498,9 @@ MagickExport void *FileToBlob(const char *filename,const size_t extent,
blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
for (i=0; blob != (unsigned char *) NULL; i+=(size_t) count)
{
- count=read(file,blob+i,quantum);
+ count=MagickRead(file,blob+i,quantum);
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
if (~i < ((size_t) count+quantum+1))
{
blob=(unsigned char *) RelinquishMagickMemory(blob);
@@ -1561,14 +1553,10 @@ MagickExport void *FileToBlob(const char *filename,const size_t extent,
(void) lseek(file,0,SEEK_SET);
for (i=0; i < *length; i+=(size_t) count)
{
- count=read(file,blob+i,(size_t) MagickMin(*length-i,(size_t)
+ count=MagickRead(file,blob+i,(size_t) MagickMin(*length-i,(size_t)
MagickMaxBufferExtent));
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
}
if (i < *length)
{
@@ -1707,13 +1695,9 @@ MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
}
for ( ; ; )
{
- count=read(file,blob,quantum);
+ count=MagickRead(file,blob,quantum);
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
length=(size_t) count;
count=WriteBlobStream(image,length,blob);
if (count != (ssize_t) length)
@@ -2401,13 +2385,9 @@ MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
length=(size_t) count;
for (i=0; i < length; i+=(size_t) count)
{
- count=write(file,p+i,(size_t) (length-i));
+ count=MagickWrite(file,p+i,(size_t) (length-i));
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
}
if (i < length)
break;
diff --git a/MagickCore/cache.c b/MagickCore/cache.c
index 8bb81d542..81f280d17 100644
--- a/MagickCore/cache.c
+++ b/MagickCore/cache.c
@@ -668,10 +668,7 @@ static MagickBooleanType ClonePixelCacheOnDisk(
length=(size_t) MagickMin((MagickSizeType) quantum,cache_info->length-
extent);
- do
- {
- count=read(cache_info->file,buffer,length);
- } while ((count < 0) && (errno == EINTR));
+ count=MagickRead(cache_info->file,buffer,length);
if (count <= 0)
{
buffer=(unsigned char *) RelinquishMagickMemory(buffer);
@@ -684,11 +681,8 @@ static MagickBooleanType ClonePixelCacheOnDisk(
while (offset < count)
{
- do
- {
- number_bytes=write(clone_info->file,buffer+offset,(size_t) (count-
- offset));
- } while ((number_bytes < 0) && (errno == EINTR));
+ number_bytes=MagickWrite(clone_info->file,buffer+offset,(size_t) (count-
+ offset));
if (number_bytes <= 0)
{
buffer=(unsigned char *) RelinquishMagickMemory(buffer);
@@ -3685,25 +3679,14 @@ static inline MagickOffsetType WritePixelCacheRegion(
ssize_t
count = 0;
-#if !defined(MAGICKCORE_HAVE_PWRITE)
if (lseek(cache_info->file,offset,SEEK_SET) < 0)
return((MagickOffsetType) -1);
-#endif
for (i=0; i < (MagickOffsetType) length; i+=count)
{
-#if !defined(MAGICKCORE_HAVE_PWRITE)
- count=write(cache_info->file,buffer+i,(size_t) MagickMin(length-
+ count=MagickWrite(cache_info->file,buffer+i,(size_t) MagickMin(length-
(MagickSizeType) i,MagickMaxBufferExtent));
-#else
- count=pwrite(cache_info->file,buffer+i,(size_t) MagickMin(length-
- (MagickSizeType) i,MagickMaxBufferExtent),offset+i);
-#endif
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
}
return(i);
}
@@ -4560,25 +4543,14 @@ static inline MagickOffsetType ReadPixelCacheRegion(
ssize_t
count = 0;
-#if !defined(MAGICKCORE_HAVE_PREAD)
if (lseek(cache_info->file,offset,SEEK_SET) < 0)
return((MagickOffsetType) -1);
-#endif
for (i=0; i < (MagickOffsetType) length; i+=count)
{
-#if !defined(MAGICKCORE_HAVE_PREAD)
- count=read(cache_info->file,buffer+i,(size_t) MagickMin(length-
+ count=MagickRead(cache_info->file,buffer+i,(size_t) MagickMin(length-
(MagickSizeType) i,(size_t) MagickMaxBufferExtent));
-#else
- count=pread(cache_info->file,buffer+i,(size_t) MagickMin(length-
- (MagickSizeType) i,(size_t) MagickMaxBufferExtent),offset+i);
-#endif
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
}
return(i);
}
diff --git a/MagickCore/distribute-cache.c b/MagickCore/distribute-cache.c
index a12b7e5f2..a7c981688 100644
--- a/MagickCore/distribute-cache.c
+++ b/MagickCore/distribute-cache.c
@@ -158,25 +158,24 @@ static inline MagickOffsetType dpc_read(SOCKET_TYPE magick_unused(file),
static inline MagickOffsetType dpc_read(SOCKET_TYPE file,
const MagickSizeType length,unsigned char *magick_restrict message)
{
- MagickOffsetType
- i;
-
- ssize_t
- count;
-
- count=0;
- for (i=0; i < (MagickOffsetType) length; i+=count)
+ MagickOffsetType offset = 0;
+ while (offset < (MagickOffsetType) length)
{
- count=recv(file,(char *) message+i,(LENGTH_TYPE) MagickMin(length-
- (MagickSizeType) i,(MagickSizeType) MagickMaxBufferExtent),0);
- if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ MagickSizeType remaining = length-(MagickSizeType) offset;
+ ssize_t count = recv(file,(char *) message+offset,(LENGTH_TYPE)
+ MagickMin(remaining,(MagickSizeType) MagickMaxBufferExtent),0);
+ if (count > 0)
+ offset+=(MagickOffsetType) count;
+ else
+ if (count == 0)
+ break;
+ else
+ {
+ if (errno != EINTR)
+ continue;
+ }
}
- return(i);
+ return(offset);
}
#endif
diff --git a/MagickCore/matrix.c b/MagickCore/matrix.c
index c4a5f589a..077ff0f2d 100644
--- a/MagickCore/matrix.c
+++ b/MagickCore/matrix.c
@@ -142,34 +142,21 @@ static inline MagickOffsetType WriteMatrixElements(
ssize_t
count;
-#if !defined(MAGICKCORE_HAVE_PWRITE)
LockSemaphoreInfo(matrix_info->semaphore);
if (lseek(matrix_info->file,offset,SEEK_SET) < 0)
{
UnlockSemaphoreInfo(matrix_info->semaphore);
return((MagickOffsetType) -1);
}
-#endif
count=0;
for (i=0; i < (MagickOffsetType) length; i+=count)
{
-#if !defined(MAGICKCORE_HAVE_PWRITE)
- count=write(matrix_info->file,buffer+i,(size_t) MagickMin(length-
+ count=MagickWrite(matrix_info->file,buffer+i,(size_t) MagickMin(length-
(MagickSizeType) i,(MagickSizeType) MagickMaxBufferExtent));
-#else
- count=pwrite(matrix_info->file,buffer+i,(size_t) MagickMin(length-
- (MagickSizeType) i,(MagickSizeType) MagickMaxBufferExtent),offset+i);
-#endif
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
}
-#if !defined(MAGICKCORE_HAVE_PWRITE)
UnlockSemaphoreInfo(matrix_info->semaphore);
-#endif
return(i);
}
@@ -499,34 +486,21 @@ static inline MagickOffsetType ReadMatrixElements(
ssize_t
count;
-#if !defined(MAGICKCORE_HAVE_PREAD)
LockSemaphoreInfo(matrix_info->semaphore);
if (lseek(matrix_info->file,offset,SEEK_SET) < 0)
{
UnlockSemaphoreInfo(matrix_info->semaphore);
return((MagickOffsetType) -1);
}
-#endif
count=0;
for (i=0; i < (MagickOffsetType) length; i+=count)
{
-#if !defined(MAGICKCORE_HAVE_PREAD)
- count=read(matrix_info->file,buffer+i,(size_t) MagickMin(length-i,
+ count=MagickRead(matrix_info->file,buffer+i,(size_t) MagickMin(length-i,
(MagickSizeType) MagickMaxBufferExtent));
-#else
- count=pread(matrix_info->file,buffer+i,(size_t) MagickMin(length-
- (MagickSizeType) i,(MagickSizeType) MagickMaxBufferExtent),offset+i);
-#endif
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
}
-#if !defined(MAGICKCORE_HAVE_PREAD)
UnlockSemaphoreInfo(matrix_info->semaphore);
-#endif
return(i);
}
@@ -1064,7 +1038,7 @@ MagickExport MagickBooleanType NullMatrix(MatrixInfo *matrix_info)
{
for (x=0; x < (ssize_t) matrix_info->length; x++)
{
- count=write(matrix_info->file,&value,sizeof(value));
+ count=MagickWrite(matrix_info->file,&value,sizeof(value));
if (count != (ssize_t) sizeof(value))
break;
}
diff --git a/MagickCore/memory.c b/MagickCore/memory.c
index 799541263..dfc8ee707 100644
--- a/MagickCore/memory.c
+++ b/MagickCore/memory.c
@@ -623,7 +623,7 @@ MagickExport void *AcquireCriticalMemory(const size_t size)
memory=AcquireMagickMemory(size);
if (memory != (void *) NULL)
return(memory);
- status=write(STDERR_FILENO,fatal_message,sizeof(fatal_message)-1);
+ status=MagickWrite(STDERR_FILENO,fatal_message,sizeof(fatal_message)-1);
(void) status;
MagickCoreTerminus();
_exit(EXIT_FAILURE);
diff --git a/MagickCore/string.c b/MagickCore/string.c
index 85c303b54..5147d62e0 100644
--- a/MagickCore/string.c
+++ b/MagickCore/string.c
@@ -625,14 +625,10 @@ MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
(void) lseek(file,0,SEEK_SET);
for (i=0; i < length; i+=(size_t) count)
{
- count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
+ count=MagickRead(file,string+i,(size_t) MagickMin(length-i,(size_t)
MagickMaxBufferExtent));
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
}
if (i < length)
{
diff --git a/MagickCore/utility-private.h b/MagickCore/utility-private.h
index 8242e5f1e..74e867353 100644
--- a/MagickCore/utility-private.h
+++ b/MagickCore/utility-private.h
@@ -49,15 +49,6 @@ extern MagickPrivate void
ChopPathComponents(char *,const size_t),
ExpandFilename(char *);
-static inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
- struct dirent **result)
-{
- (void) entry;
- errno=0;
- *result=readdir(directory);
- return(errno);
-}
-
static inline int access_utf8(const char *path,int mode)
{
if (path == (const char *) NULL)
@@ -102,6 +93,55 @@ static inline MagickBooleanType is_symlink_utf8(const char *path)
#endif
}
+static inline ssize_t MagickRead(int fd,void *buffer,size_t extent)
+{
+ unsigned char *p = (unsigned char *) buffer;
+ size_t offset = 0;
+ while (offset < extent)
+ {
+ ssize_t count = read(fd,p+offset,extent-offset);
+ if (count < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ return(-1);
+ }
+ if (count == 0)
+ break;
+ offset+=(size_t) count;
+ }
+ return((ssize_t) offset);
+}
+
+static inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
+ struct dirent **result)
+{
+ (void) entry;
+ errno=0;
+ *result=readdir(directory);
+ return(errno);
+}
+
+static inline ssize_t MagickWrite(int fd,const void *buffer,size_t extent)
+{
+ const unsigned char *p = (const unsigned char *) buffer;
+ size_t offset = 0;
+ while (offset < extent)
+ {
+ ssize_t count = write(fd,p+offset,extent-offset);
+ if (count < 0) {
+ if (errno == EINTR)
+ continue;
+ return(-1);
+ }
+ if (count == 0)
+ break;
+ offset+=(size_t) count;
+ }
+ return((ssize_t) offset);
+}
+
+
static inline int open_utf8(const char *path,int flags,mode_t mode)
{
#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
diff --git a/MagickCore/utility.c b/MagickCore/utility.c
index cb3252256..7a84c0c74 100644
--- a/MagickCore/utility.c
+++ b/MagickCore/utility.c
@@ -2078,14 +2078,10 @@ MagickPrivate MagickBooleanType ShredFile(const char *path)
{
if (i != 0)
SetRandomKey(random_info,quantum,GetStringInfoDatum(key));
- count=write(file,GetStringInfoDatum(key),(size_t)
+ count=MagickWrite(file,GetStringInfoDatum(key),(size_t)
MagickMin((MagickOffsetType) quantum,(MagickOffsetType) length-j));
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
}
if (j < (MagickOffsetType) length)
break;
diff --git a/MagickCore/xml-tree.c b/MagickCore/xml-tree.c
index 4736545ad..23e45272b 100644
--- a/MagickCore/xml-tree.c
+++ b/MagickCore/xml-tree.c
@@ -580,13 +580,9 @@ MagickPrivate char *FileToXML(const char *filename,const size_t extent)
xml=(char *) AcquireQuantumMemory(quantum,sizeof(*xml));
for (i=0; xml != (char *) NULL; i+=(size_t) count)
{
- count=read(file,xml+i,quantum);
+ count=MagickRead(file,xml+i,quantum);
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
if (~((size_t) i) < (quantum+1))
{
xml=(char *) RelinquishMagickMemory(xml);
@@ -629,14 +625,10 @@ MagickPrivate char *FileToXML(const char *filename,const size_t extent)
(void) lseek(file,0,SEEK_SET);
for (i=0; i < length; i+=(size_t) count)
{
- count=read(file,xml+i,(size_t) MagickMin(length-i,(size_t)
+ count=MagickRead(file,xml+i,(size_t) MagickMin(length-i,(size_t)
MagickMaxBufferExtent));
if (count <= 0)
- {
- count=0;
- if (errno != EINTR)
- break;
- }
+ break;
}
if (i < length)
{
diff --git a/coders/ps.c b/coders/ps.c
index 0a0cc5e46..94befbc4e 100644
--- a/coders/ps.c
+++ b/coders/ps.c
@@ -745,7 +745,7 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
(void) CopyMagickString(command,"/setpagedevice {pop} bind 1 index where {"
"dup wcheck {3 1 roll put} {pop def} ifelse} {def} ifelse\n",
MagickPathExtent);
- count=write(file,command,(unsigned int) strlen(command));
+ count=MagickWrite(file,command,(unsigned int) strlen(command));
if (image_info->page == (char *) NULL)
{
char
@@ -753,7 +753,7 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
(void) FormatLocaleString(translate_geometry,MagickPathExtent,
"%g %g translate\n",-info.bounds.x1,-info.bounds.y1);
- count=write(file,translate_geometry,(unsigned int)
+ count=MagickWrite(file,translate_geometry,(unsigned int)
strlen(translate_geometry));
}
(void) count;