Commit 64330ffff for imagemagick.org
commit 64330ffff8d4ca15877e77668622e317891c8b0a
Author: Cristy <urban-warrior@imagemagick.org>
Date: Sun Nov 15 08:53:33 2026 -0500
fix a relative-path bug when checking whether expanded entries are directories
diff --git a/MagickCore/utility.c b/MagickCore/utility.c
index 26df67de7..cd64f6f2a 100644
--- a/MagickCore/utility.c
+++ b/MagickCore/utility.c
@@ -79,6 +79,34 @@
*/
static const char
Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/*
+ O(1) ASCII-to-Base64 reverse lookup table:
+ 0..63 : valid Base64 sextet value
+ -1 : invalid character
+ -2 : ASCII whitespace (' ', '\t', '\n', '\r', '\v', '\f')
+ -3 : padding character ('=')
+*/
+static const signed char
+ Base64DecodeTable[256] =
+ {
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-1,-1, /* 0x00..0x0F */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0x10..0x1F */
+ -2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, /* 0x20..0x2F (' ', '+', '/') */
+ 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-3,-1,-1, /* 0x30..0x3F ('0'-'9', '=') */
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, /* 0x40..0x4F ('A'-'O') */
+ 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, /* 0x50..0x5F ('P'-'Z') */
+ -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, /* 0x60..0x6F ('a'-'o') */
+ 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, /* 0x70..0x7F ('p'-'z') */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0x80..0x8F */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0x90..0x9F */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0xA0..0xAF */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0xB0..0xBF */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0xC0..0xCF */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0xD0..0xDF */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0xE0..0xEF */
+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 /* 0xF0..0xFF */
+ };
/*
Forward declaration.
@@ -117,7 +145,7 @@ MagickExport MagickBooleanType AcquireUniqueFilename(char *path)
file=AcquireUniqueFileResource(path);
if (file == -1)
return(MagickFalse);
- file=close_utf8(file)-1;
+ (void) close_utf8(file);
return(MagickTrue);
}
@@ -190,7 +218,8 @@ MagickExport MagickBooleanType AcquireUniqueSymbolicLink(const char *source,
passes=GetShredPasses();
if ((passes == 0) && (status != MagickFalse))
{
- (void) AcquireUniqueFilename(destination);
+ if (AcquireUniqueFilename(destination) == MagickFalse)
+ return(MagickFalse);
(void) RelinquishUniqueFileResource(destination);
if (*source == *DirectorySeparator)
{
@@ -205,6 +234,9 @@ MagickExport MagickBooleanType AcquireUniqueSymbolicLink(const char *source,
*path='\0';
if (getcwd(path,MagickPathExtent) == (char *) NULL)
return(MagickFalse);
+ if ((strlen(path)+strlen(DirectorySeparator)+strlen(source)) >=
+ MagickPathExtent)
+ return(MagickFalse);
(void) ConcatenateMagickString(path,DirectorySeparator,
MagickPathExtent);
(void) ConcatenateMagickString(path,source,MagickPathExtent);
@@ -242,18 +274,49 @@ MagickExport MagickBooleanType AcquireUniqueSymbolicLink(const char *source,
for (length=0; ; )
{
count=(ssize_t) read(source_file,buffer,quantum);
- if (count <= 0)
- break;
- length=(size_t) count;
- count=(ssize_t) write(destination_file,buffer,length);
- if ((size_t) count != length)
+ if (count < 0)
{
+ if (errno == EINTR)
+ continue;
(void) RelinquishUniqueFileResource(destination);
status=MagickFalse;
break;
}
+ if (count == 0)
+ break;
+ length=(size_t) count;
+ {
+ size_t
+ written;
+
+ written=0;
+ while (written < length)
+ {
+ count=(ssize_t) write(destination_file,buffer+written,length-written);
+ if (count < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ break;
+ }
+ if (count == 0)
+ break;
+ written+=(size_t) count;
+ }
+ if (written != length)
+ {
+ (void) RelinquishUniqueFileResource(destination);
+ status=MagickFalse;
+ break;
+ }
+ }
}
- (void) close_utf8(destination_file);
+ if (close_utf8(destination_file) != 0)
+ {
+ if (status != MagickFalse)
+ (void) RelinquishUniqueFileResource(destination);
+ status=MagickFalse;
+ }
(void) close_utf8(source_file);
buffer=(unsigned char *) RelinquishMagickMemory(buffer);
return(status);
@@ -358,11 +421,11 @@ MagickExport unsigned char *Base64Decode(const char *source,size_t *length)
state;
const char
- *p,
- *q;
+ *p;
size_t
- i;
+ i,
+ source_length;
unsigned char
*decode;
@@ -372,7 +435,10 @@ MagickExport unsigned char *Base64Decode(const char *source,size_t *length)
if (IsEventLogging() != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
*length=0;
- decode=(unsigned char *) AcquireQuantumMemory((strlen(source)+3)/4,
+ source_length=strlen(source);
+ if (source_length > (SIZE_MAX-3))
+ return((unsigned char *) NULL);
+ decode=(unsigned char *) AcquireQuantumMemory((source_length+3)/4,
3*sizeof(*decode));
if (decode == (unsigned char *) NULL)
return((unsigned char *) NULL);
@@ -380,12 +446,15 @@ MagickExport unsigned char *Base64Decode(const char *source,size_t *length)
state=0;
for (p=source; *p != '\0'; p++)
{
- if (isspace((int) ((unsigned char) *p)) != 0)
+ signed char
+ value;
+
+ value=Base64DecodeTable[(unsigned char) *p];
+ if (value == -2)
continue;
- if (*p == '=')
+ if (value == -3)
break;
- q=strchr(Base64,*p);
- if (q == (char *) NULL)
+ if (value < 0)
{
decode=(unsigned char *) RelinquishMagickMemory(decode);
return((unsigned char *) NULL); /* non-Base64 character */
@@ -394,27 +463,27 @@ MagickExport unsigned char *Base64Decode(const char *source,size_t *length)
{
case 0:
{
- decode[i]=(unsigned char)((q-Base64) << 2);
+ decode[i]=(unsigned char) (value << 2);
state++;
break;
}
case 1:
{
- decode[i++]|=(unsigned char)((q-Base64) >> 4);
- decode[i]=(unsigned char)(((q-Base64) & 0x0f) << 4);
+ decode[i++]|=(unsigned char) (value >> 4);
+ decode[i]=(unsigned char) ((value & 0x0f) << 4);
state++;
break;
}
case 2:
{
- decode[i++]|=(unsigned char)((q-Base64) >> 2);
- decode[i]=(unsigned char)(((q-Base64) & 0x03) << 6);
+ decode[i++]|=(unsigned char) (value >> 2);
+ decode[i]=(unsigned char) ((value & 0x03) << 6);
state++;
break;
}
case 3:
{
- decode[i++]|=(unsigned char)(q-Base64);
+ decode[i++]|=(unsigned char) value;
state=0;
break;
}
@@ -448,7 +517,7 @@ MagickExport unsigned char *Base64Decode(const char *source,size_t *length)
case 2:
{
for ( ; *p != '\0'; p++)
- if (isspace((int) ((unsigned char) *p)) == 0)
+ if (Base64DecodeTable[(unsigned char) *p] != -2)
break;
if (*p != '=')
{
@@ -456,11 +525,12 @@ MagickExport unsigned char *Base64Decode(const char *source,size_t *length)
return((unsigned char *) NULL);
}
p++;
+ magick_fallthrough;
}
case 3:
{
for ( ; *p != '\0'; p++)
- if (isspace((int) ((unsigned char) *p)) == 0)
+ if (Base64DecodeTable[(unsigned char) *p] != -2)
{
decode=(unsigned char *) RelinquishMagickMemory(decode);
return((unsigned char *) NULL);
@@ -515,12 +585,11 @@ MagickExport char *Base64Encode(const unsigned char *blob,
*encode;
const unsigned char
+ *end,
*p;
size_t
- i;
-
- size_t
+ i,
remainder;
assert(blob != (const unsigned char *) NULL);
@@ -533,14 +602,15 @@ MagickExport char *Base64Encode(const unsigned char *blob,
if (encode == (char *) NULL)
return((char *) NULL);
i=0;
- for (p=blob; p < (blob+blob_length-2); p+=(ptrdiff_t) 3)
+ remainder=blob_length % 3;
+ end=blob+(blob_length-remainder);
+ for (p=blob; p < end; p+=(ptrdiff_t) 3)
{
encode[i++]=Base64[(int) (*p >> 2)];
encode[i++]=Base64[(int) (((*p & 0x03) << 4)+(*(p+1) >> 4))];
encode[i++]=Base64[(int) (((*(p+1) & 0x0f) << 2)+(*(p+2) >> 6))];
encode[i++]=Base64[(int) (*(p+2) & 0x3f)];
}
- remainder=blob_length % 3;
if (remainder != 0)
{
ssize_t
@@ -681,7 +751,7 @@ MagickPrivate void ExpandFilename(char *path)
entry=getpwnam(username);
#else
entry=(struct passwd *) NULL;
- if (getpwnam_r(username,&pwd,buffer,sizeof(buffer),&entry) < 0)
+ if (getpwnam_r(username,&pwd,buffer,sizeof(buffer),&entry) != 0)
return;
#endif
if (entry == (struct passwd *) NULL)
@@ -782,7 +852,8 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
j;
size_t
- number_files;
+ number_files,
+ vector_capacity;
ssize_t
count,
@@ -795,8 +866,10 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
assert(arguments != (char ***) NULL);
if (IsEventLogging() != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
- vector=(char **) AcquireQuantumMemory((size_t) (*number_arguments+1),
- sizeof(*vector));
+ if (*number_arguments < 0)
+ return(MagickFalse);
+ vector_capacity=(size_t) *number_arguments+1;
+ vector=(char **) AcquireQuantumMemory(vector_capacity,sizeof(*vector));
if (vector == (char **) NULL)
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
/*
@@ -823,6 +896,14 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
*filename='\0';
*subimage='\0';
number_files=0;
+ if ((size_t) (count+1) >= vector_capacity)
+ {
+ vector_capacity=(size_t) count+2;
+ vector=(char **) ResizeQuantumMemory(vector,vector_capacity,
+ sizeof(*vector));
+ if (vector == (char **) NULL)
+ ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+ }
vector[count++]=ConstantString(option);
destroy=MagickTrue;
parameters=ParseCommandOption(MagickCommandOptions,MagickFalse,option);
@@ -837,6 +918,15 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
if (i == (ssize_t) *number_arguments)
break;
option=(*arguments)[i];
+ if ((size_t) (count+1) >= vector_capacity)
+ {
+ vector_capacity=(size_t) count+2;
+ vector=(char **) ResizeQuantumMemory(vector,vector_capacity,
+ sizeof(*vector));
+ if (vector == (char **) NULL)
+ ThrowFatalException(ResourceLimitFatalError,
+ "MemoryAllocationFailed");
+ }
vector[count++]=ConstantString(option);
}
continue;
@@ -887,19 +977,41 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
if (files == (char *) NULL)
continue;
filelist=StringToArgv(files,&length);
+ files=DestroyString(files);
if (filelist == (char **) NULL)
continue;
- files=DestroyString(files);
+ if (length <= 1)
+ {
+ if (length == 1)
+ filelist[0]=DestroyString(filelist[0]);
+ filelist=(char **) RelinquishMagickMemory(filelist);
+ continue;
+ }
filelist[0]=DestroyString(filelist[0]);
for (j=0; j < (ssize_t) (length-1); j++)
filelist[j]=filelist[j+1];
- number_files=(size_t) length-1;
+ number_files=(size_t) (length-1);
}
if (filelist == (char **) NULL)
continue;
for (j=0; j < (ssize_t) number_files; j++)
- if (IsPathDirectory(filelist[j]) <= 0)
+ {
+ char
+ candidate[MagickPathExtent];
+
+ if (*path != '\0')
+ {
+ (void) CopyMagickString(candidate,path,MagickPathExtent);
+ (void) ConcatenateMagickString(candidate,DirectorySeparator,
+ MagickPathExtent);
+ (void) ConcatenateMagickString(candidate,filelist[j],
+ MagickPathExtent);
+ }
+ else
+ (void) CopyMagickString(candidate,filelist[j],MagickPathExtent);
+ if (IsPathDirectory(candidate) <= 0)
break;
+ }
if (j == (ssize_t) number_files)
{
for (j=0; j < (ssize_t) number_files; j++)
@@ -910,14 +1022,20 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
/*
Transfer file list to argument vector.
*/
- vector=(char **) ResizeQuantumMemory(vector,(size_t) ((ssize_t)
- *number_arguments+count+(ssize_t) number_files+1),sizeof(*vector));
- if (vector == (char **) NULL)
+ if (((size_t) count+number_files+((size_t) *number_arguments-(size_t) i)) >=
+ vector_capacity)
{
- for (j=0; j < (ssize_t) number_files; j++)
- filelist[j]=DestroyString(filelist[j]);
- filelist=(char **) RelinquishMagickMemory(filelist);
- return(MagickFalse);
+ vector_capacity=(size_t) count+number_files+
+ ((size_t) *number_arguments-(size_t) i)+1;
+ vector=(char **) ResizeQuantumMemory(vector,vector_capacity,
+ sizeof(*vector));
+ if (vector == (char **) NULL)
+ {
+ for (j=0; j < (ssize_t) number_files; j++)
+ filelist[j]=DestroyString(filelist[j]);
+ filelist=(char **) RelinquishMagickMemory(filelist);
+ return(MagickFalse);
+ }
}
for (j=0; j < (ssize_t) number_files; j++)
{
@@ -931,14 +1049,21 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
/*
Do not expand command option parameters.
*/
- vector[count++]=ConstantString(option);
+ if (destroy != MagickFalse)
+ {
+ count--;
+ vector[count]=DestroyString(vector[count]);
+ destroy=MagickFalse;
+ }
+ vector[count++]=option;
+ filelist[j]=(char *) NULL;
for (k=0; k < parameters; k++)
{
j++;
if (j == (ssize_t) number_files)
break;
- option=filelist[j];
- vector[count++]=ConstantString(option);
+ vector[count++]=filelist[j];
+ filelist[j]=(char *) NULL;
}
continue;
}
@@ -1116,14 +1241,15 @@ MagickPrivate MagickBooleanType GetExecutionPath(char *path,const size_t extent)
if (*program_invocation_name != '/')
{
size_t
- extent;
+ name_extent;
- extent=strlen(directory)+strlen(program_name)+2;
- program_name=AcquireQuantumMemory(extent,sizeof(*program_name));
+ name_extent=strlen(directory)+strlen(program_name)+2;
+ program_name=(char *) AcquireQuantumMemory(name_extent,
+ sizeof(*program_name));
if (program_name == (char *) NULL)
program_name=program_invocation_name;
else
- count=FormatLocaleString(program_name,extent,"%s/%s",directory,
+ count=FormatLocaleString(program_name,name_extent,"%s/%s",directory,
program_invocation_name);
}
if (count != -1)
@@ -1263,12 +1389,11 @@ MagickExport void GetPathComponent(const char *path,PathType type,
char *component)
{
char
+ *p,
*q;
- char
- *p;
-
size_t
+ component_length,
magick_length,
subimage_offset,
subimage_length;
@@ -1283,12 +1408,13 @@ MagickExport void GetPathComponent(const char *path,PathType type,
return;
}
(void) CopyMagickString(component,path,MagickPathExtent);
+ component_length=strlen(component);
subimage_length=0;
subimage_offset=0;
if (type != SubcanonicalPath)
{
- p=component+strlen(component)-1;
- if ((strlen(component) > 2) && (*p == ']'))
+ p=component+component_length-1;
+ if ((component_length > 2) && (*p == ']'))
{
q=strrchr(component,'[');
if (q != (char *) NULL)
@@ -1321,7 +1447,7 @@ MagickExport void GetPathComponent(const char *path,PathType type,
}
magick_length=0;
#if defined(__OS2__)
- if (path[1] != ":")
+ if (path[1] != ':')
#endif
for (p=component; *p != '\0'; p++)
{
@@ -1497,6 +1623,8 @@ MagickPrivate char **GetPathComponents(const char *path,
ssize_t
i;
+ assert(number_components != (size_t *) NULL);
+ *number_components=0;
if (path == (char *) NULL)
return((char **) NULL);
*number_components=1;
@@ -1506,7 +1634,10 @@ MagickPrivate char **GetPathComponents(const char *path,
components=(char **) AcquireQuantumMemory((size_t) *number_components+1UL,
sizeof(*components));
if (components == (char **) NULL)
- return((char **) NULL);
+ {
+ *number_components=0;
+ return((char **) NULL);
+ }
p=path;
for (i=0; i < (ssize_t) *number_components; i++)
{
@@ -1523,6 +1654,7 @@ MagickPrivate char **GetPathComponents(const char *path,
for (j=0; j < i; j++)
components[j]=DestroyString(components[j]);
components=(char **) RelinquishMagickMemory(components);
+ *number_components=0;
return((char **) NULL);
}
(void) CopyMagickString(components[i],p,(size_t) (q-p+1));
@@ -1568,9 +1700,13 @@ MagickExport MagickBooleanType GetPathTemplate(char *path)
MagickBooleanType
status;
+ size_t
+ directory_length;
+
struct stat
attributes;
+ assert(path != (char *) NULL);
(void) FormatLocaleString(path,MagickPathExtent,"magick-"
MagickPathTemplate);
exception=AcquireExceptionInfo();
@@ -1605,7 +1741,10 @@ MagickExport MagickBooleanType GetPathTemplate(char *path)
(void) CloneString(&directory,value);
value=DestroyString(value);
}
- if (strlen(directory) > (MagickPathExtent-25))
+ if (directory == (char *) NULL)
+ return(MagickFalse);
+ directory_length=strlen(directory);
+ if ((directory_length == 0) || (directory_length > (MagickPathExtent-25)))
{
directory=DestroyString(directory);
return(MagickFalse);
@@ -1616,7 +1755,7 @@ MagickExport MagickBooleanType GetPathTemplate(char *path)
directory=DestroyString(directory);
return(MagickFalse);
}
- if (directory[strlen(directory)-1] == *DirectorySeparator)
+ if (directory[directory_length-1] == *DirectorySeparator)
(void) FormatLocaleString(path,MagickPathExtent,"%smagick-"
MagickPathTemplate,directory);
else
@@ -1717,7 +1856,7 @@ static int IsPathDirectory(const char *path)
attributes;
if ((path == (const char *) NULL) || (*path == '\0'))
- return(MagickFalse);
+ return(-1);
status=GetPathAttributes(path,&attributes);
if (status == MagickFalse)
return(-1);
@@ -1784,18 +1923,20 @@ MagickPrivate char **ListFiles(const char *directory,const char *pattern,
size_t *number_entries)
{
char
- **filelist;
+ **filelist,
+ full_path[MagickPathExtent];
DIR
*current_directory;
+ size_t
+ directory_length,
+ max_entries;
+
struct dirent
*buffer,
*entry;
- size_t
- max_entries;
-
/*
Open directory.
*/
@@ -1819,9 +1960,6 @@ MagickPrivate char **ListFiles(const char *directory,const char *pattern,
(void) closedir(current_directory);
return((char **) NULL);
}
- /*
- Save the current and change to the new directory.
- */
buffer=(struct dirent *) AcquireMagickMemory(sizeof(*buffer)+FILENAME_MAX+1);
if (buffer == (struct dirent *) NULL)
{
@@ -1829,13 +1967,25 @@ MagickPrivate char **ListFiles(const char *directory,const char *pattern,
(void) closedir(current_directory);
return((char **) NULL);
}
+ directory_length=strlen(directory);
while ((MagickReadDirectory(current_directory,buffer,&entry) == 0) &&
(entry != (struct dirent *) NULL))
{
+ int
+ is_directory;
+
if ((LocaleCompare(entry->d_name,".") == 0) ||
(LocaleCompare(entry->d_name,"..") == 0))
continue;
- if ((IsPathDirectory(entry->d_name) > 0) ||
+ if ((directory_length > 0) &&
+ (directory[directory_length-1] == *DirectorySeparator))
+ (void) FormatLocaleString(full_path,MagickPathExtent,"%s%s",directory,
+ entry->d_name);
+ else
+ (void) FormatLocaleString(full_path,MagickPathExtent,"%s%s%s",directory,
+ DirectorySeparator,entry->d_name);
+ is_directory=IsPathDirectory(full_path);
+ if ((is_directory > 0) ||
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
(GlobExpression(entry->d_name,pattern,MagickTrue) != MagickFalse))
#else
@@ -1844,14 +1994,27 @@ MagickPrivate char **ListFiles(const char *directory,const char *pattern,
{
if (*number_entries >= max_entries)
{
+ char
+ **resized_filelist;
+
/*
Extend the file list.
*/
max_entries<<=1;
- filelist=(char **) ResizeQuantumMemory(filelist,(size_t)
+ resized_filelist=(char **) ResizeQuantumMemory(filelist,(size_t)
max_entries,sizeof(*filelist));
- if (filelist == (char **) NULL)
- break;
+ if (resized_filelist == (char **) NULL)
+ {
+ size_t
+ i;
+
+ for (i=0; i < *number_entries; i++)
+ filelist[i]=DestroyString(filelist[i]);
+ filelist=(char **) RelinquishMagickMemory(filelist);
+ *number_entries=0;
+ break;
+ }
+ filelist=resized_filelist;
}
#if defined(vms)
{
@@ -1913,27 +2076,59 @@ MagickExport void MagickDelay(const MagickSizeType milliseconds)
#if defined(MAGICKCORE_HAVE_NANOSLEEP)
{
struct timespec
+ remaining,
timer;
timer.tv_sec=(time_t) (milliseconds/1000);
- timer.tv_nsec=(time_t) ((milliseconds % 1000)*1000*1000);
- (void) nanosleep(&timer,(struct timespec *) NULL);
+ timer.tv_nsec=(long) ((milliseconds % 1000)*1000*1000);
+ while ((nanosleep(&timer,&remaining) == -1) && (errno == EINTR))
+ timer=remaining;
}
#elif defined(MAGICKCORE_HAVE_USLEEP)
- usleep(1000*milliseconds);
+ {
+ MagickSizeType
+ remaining;
+
+ remaining=milliseconds;
+ while (remaining > 0)
+ {
+ useconds_t
+ chunk;
+
+ chunk=(useconds_t) (remaining > 500000 ? 500000 : remaining)*1000;
+ (void) usleep(chunk);
+ remaining-=(MagickSizeType) (chunk/1000);
+ }
+ }
#elif defined(MAGICKCORE_HAVE_SELECT)
{
struct timeval
timer;
- timer.tv_sec=(long) milliseconds/1000;
- timer.tv_usec=(long) (milliseconds % 1000)*1000;
+ timer.tv_sec=(long) (milliseconds/1000);
+ timer.tv_usec=(long) ((milliseconds % 1000)*1000);
(void) select(0,(XFD_SET *) NULL,(XFD_SET *) NULL,(XFD_SET *) NULL,&timer);
}
#elif defined(MAGICKCORE_HAVE_POLL)
- (void) poll((struct pollfd *) NULL,0,(int) milliseconds);
+ (void) poll((struct pollfd *) NULL,0,(int) (milliseconds > INT_MAX ? INT_MAX :
+ milliseconds));
#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
- Sleep((long) milliseconds);
+ {
+ MagickSizeType
+ remaining;
+
+ remaining=milliseconds;
+ while (remaining > 0)
+ {
+ DWORD
+ chunk;
+
+ chunk=(DWORD) (remaining > (MagickSizeType) 0x7fffffff ? 0x7fffffff :
+ remaining);
+ Sleep(chunk);
+ remaining-=(MagickSizeType) chunk;
+ }
+ }
#elif defined(vms)
{
float
@@ -1949,7 +2144,7 @@ MagickExport void MagickDelay(const MagickSizeType milliseconds)
clock_t
time_end;
- time_end=clock()+milliseconds*CLOCKS_PER_SEC/1000;
+ time_end=clock()+(clock_t) (milliseconds*CLOCKS_PER_SEC/1000);
while (clock() < time_end)
{
}
@@ -2058,12 +2253,31 @@ MagickPrivate MagickBooleanType ShredFile(const char *path)
file=open_utf8(path,O_WRONLY | O_CLOEXEC | O_EXCL | O_BINARY,S_MODE);
if (file == -1)
return(MagickFalse);
- quantum=(size_t) MagickMinBufferExtent;
- if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
- quantum=(size_t) MagickMin(file_stats.st_size,MagickMinBufferExtent);
+ if ((fstat(file,&file_stats) != 0) || (file_stats.st_size < 0))
+ {
+ (void) close_utf8(file);
+ return(MagickFalse);
+ }
+ if (file_stats.st_size == 0)
+ {
+ status=close_utf8(file);
+ return(status == -1 ? MagickFalse : MagickTrue);
+ }
+ quantum=(size_t) MagickMin(file_stats.st_size,MagickMinBufferExtent);
length=(MagickSizeType) file_stats.st_size;
random_info=AcquireRandomInfo();
+ if (random_info == (RandomInfo *) NULL)
+ {
+ (void) close_utf8(file);
+ return(MagickFalse);
+ }
key=GetRandomKey(random_info,quantum);
+ if (key == (StringInfo *) NULL)
+ {
+ random_info=DestroyRandomInfo(random_info);
+ (void) close_utf8(file);
+ return(MagickFalse);
+ }
for (i=0; i < passes; i++)
{
MagickOffsetType