1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                  SSSSS   TTTTT  RRRR   IIIII  N   N   GGGG                  %
7 %                  SS        T    R   R    I    NN  N  G                      %
8 %                   SSS      T    RRRR     I    N N N  G GGG                  %
9 %                     SS     T    R R      I    N  NN  G   G                  %
10 %                  SSSSS     T    R  R   IIIII  N   N   GGGG                  %
11 %                                                                             %
12 %                                                                             %
13 %                        MagickCore String Methods                            %
14 %                                                                             %
15 %                             Software Design                                 %
16 %                                  Cristy                                     %
17 %                               August 2003                                   %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization      %
21 %  dedicated to making software imaging solutions freely available.           %
22 %                                                                             %
23 %  You may not use this file except in compliance with the license.  You may  %
24 %  obtain a copy of the license at                                            %
25 %                                                                             %
26 %    https://imagemagick.org/script/license.php                               %
27 %                                                                             %
28 %  unless required by applicable law or agreed to in writing, software        %
29 %  distributed under the license is distributed on an "as is" basis,          %
30 %  without warranties or conditions of any kind, either express or implied.   %
31 %  See the license for the specific language governing permissions and        %
32 %  limitations under the license.                                             %
33 %                                                                             %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 */
38 
39 /*
40   Include declarations.
41 */
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/exception.h"
46 #include "MagickCore/exception-private.h"
47 #include "MagickCore/image-private.h"
48 #include "MagickCore/list.h"
49 #include "MagickCore/locale_.h"
50 #include "MagickCore/log.h"
51 #include "MagickCore/memory_.h"
52 #include "MagickCore/memory-private.h"
53 #include "MagickCore/nt-base-private.h"
54 #include "MagickCore/property.h"
55 #include "MagickCore/resource_.h"
56 #include "MagickCore/signature-private.h"
57 #include "MagickCore/string_.h"
58 #include "MagickCore/string-private.h"
59 #include "MagickCore/utility-private.h"
60 
61 /*
62   Define declarations.
63 */
64 #define CharsPerLine  0x14
65 
66 /*
67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
68 %                                                                             %
69 %                                                                             %
70 %                                                                             %
71 %   A c q u i r e S t r i n g                                                 %
72 %                                                                             %
73 %                                                                             %
74 %                                                                             %
75 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76 %
77 %  AcquireString() returns an new extended string, containing a clone of the
78 %  given string.
79 %
80 %  An extended string is the string length, plus an extra MagickPathExtent space
81 %  to allow for the string to be actively worked on.
82 %
83 %  The returned string shoud be freed using DestoryString().
84 %
85 %  The format of the AcquireString method is:
86 %
87 %      char *AcquireString(const char *source)
88 %
89 %  A description of each parameter follows:
90 %
91 %    o source: A character string.
92 %
93 */
AcquireString(const char * source)94 MagickExport char *AcquireString(const char *source)
95 {
96   char
97     *destination;
98 
99   size_t
100     length;
101 
102   length=0;
103   if (source != (char *) NULL)
104     length+=strlen(source);
105   if (~length < MagickPathExtent)
106     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
107   destination=(char *) AcquireQuantumMemory(length+MagickPathExtent,
108     sizeof(*destination));
109   if (destination == (char *) NULL)
110     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
111   if (source != (char *) NULL)
112     (void) memcpy(destination,source,length*sizeof(*destination));
113   destination[length]='\0';
114   return(destination);
115 }
116 
117 /*
118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
119 %                                                                             %
120 %                                                                             %
121 %                                                                             %
122 %   A c q u i r e S t r i n g I n f o                                         %
123 %                                                                             %
124 %                                                                             %
125 %                                                                             %
126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127 %
128 %  AcquireStringInfo() allocates the StringInfo structure.
129 %
130 %  The format of the AcquireStringInfo method is:
131 %
132 %      StringInfo *AcquireStringInfo(const size_t length)
133 %
134 %  A description of each parameter follows:
135 %
136 %    o length: the string length.
137 %
138 */
139 
AcquireStringInfoContainer()140 static StringInfo *AcquireStringInfoContainer()
141 {
142   StringInfo
143     *string_info;
144 
145   string_info=(StringInfo *) AcquireCriticalMemory(sizeof(*string_info));
146   (void) memset(string_info,0,sizeof(*string_info));
147   string_info->signature=MagickCoreSignature;
148   return(string_info);
149 }
150 
AcquireStringInfo(const size_t length)151 MagickExport StringInfo *AcquireStringInfo(const size_t length)
152 {
153   StringInfo
154     *string_info;
155 
156   string_info=AcquireStringInfoContainer();
157   string_info->length=length;
158   if (~string_info->length >= (MagickPathExtent-1))
159     string_info->datum=(unsigned char *) AcquireQuantumMemory(
160       string_info->length+MagickPathExtent,sizeof(*string_info->datum));
161   if (string_info->datum == (unsigned char *) NULL)
162     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
163   (void) memset(string_info->datum,0,(length+MagickPathExtent)*
164     sizeof(*string_info->datum));
165   return(string_info);
166 }
167 
168 /*
169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170 %                                                                             %
171 %                                                                             %
172 %                                                                             %
173 %   B l o b T o S t r i n g I n f o                                           %
174 %                                                                             %
175 %                                                                             %
176 %                                                                             %
177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178 %
179 %  BlobToStringInfo() returns the contents of a blob as a StringInfo structure
180 %  with MagickPathExtent extra space.
181 %
182 %  The format of the BlobToStringInfo method is:
183 %
184 %      StringInfo *BlobToStringInfo(const void *blob,const size_t length)
185 %
186 %  A description of each parameter follows:
187 %
188 %    o blob: the blob.
189 %
190 %    o length: the length of the blob.
191 %
192 */
BlobToStringInfo(const void * blob,const size_t length)193 MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
194 {
195   StringInfo
196     *string_info;
197 
198   if (~length < MagickPathExtent)
199     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
200   string_info=AcquireStringInfoContainer();
201   string_info->length=length;
202   string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
203     MagickPathExtent,sizeof(*string_info->datum));
204   if (string_info->datum == (unsigned char *) NULL)
205     {
206       string_info=DestroyStringInfo(string_info);
207       return((StringInfo *) NULL);
208     }
209   if (blob != (const void *) NULL)
210     (void) memcpy(string_info->datum,blob,length);
211   else
212     (void) memset(string_info->datum,0,length*sizeof(*string_info->datum));
213   (void) memset(string_info->datum+length,0,MagickPathExtent*
214     sizeof(*string_info->datum));
215   return(string_info);
216 }
217 
218 /*
219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 %                                                                             %
221 %                                                                             %
222 %                                                                             %
223 %   C l o n e S t r i n g                                                     %
224 %                                                                             %
225 %                                                                             %
226 %                                                                             %
227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
228 %
229 %  CloneString() replaces or frees the destination string to make it
230 %  a clone of the input string plus MagickPathExtent more space so the string
231 %  may be worked on.
232 %
233 %  If source is a NULL pointer the destination string will be freed and set to
234 %  a NULL pointer.  A pointer to the stored in the destination is also returned.
235 %
236 %  When finished the non-NULL string should be freed using DestoryString()
237 %  or using CloneString() with a NULL pointed for the source.
238 %
239 %  The format of the CloneString method is:
240 %
241 %      char *CloneString(char **destination,const char *source)
242 %
243 %  A description of each parameter follows:
244 %
245 %    o destination:  A pointer to a character string.
246 %
247 %    o source: A character string.
248 %
249 */
CloneString(char ** destination,const char * source)250 MagickExport char *CloneString(char **destination,const char *source)
251 {
252   size_t
253     length;
254 
255   assert(destination != (char **) NULL);
256   if (source == (const char *) NULL)
257     {
258       if (*destination != (char *) NULL)
259         *destination=DestroyString(*destination);
260       return(*destination);
261     }
262   if (*destination == (char *) NULL)
263     {
264       *destination=AcquireString(source);
265       return(*destination);
266     }
267   length=strlen(source);
268   if (~length < MagickPathExtent)
269     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
270   *destination=(char *) ResizeQuantumMemory(*destination,length+
271     MagickPathExtent,sizeof(**destination));
272   if (*destination == (char *) NULL)
273     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
274   if (length != 0)
275     (void) memcpy(*destination,source,length*sizeof(**destination));
276   (*destination)[length]='\0';
277   return(*destination);
278 }
279 
280 /*
281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282 %                                                                             %
283 %                                                                             %
284 %                                                                             %
285 %   C l o n e S t r i n g I n f o                                             %
286 %                                                                             %
287 %                                                                             %
288 %                                                                             %
289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
290 %
291 %  CloneStringInfo() clones a copy of the StringInfo structure.
292 %
293 %  The format of the CloneStringInfo method is:
294 %
295 %      StringInfo *CloneStringInfo(const StringInfo *string_info)
296 %
297 %  A description of each parameter follows:
298 %
299 %    o string_info: the string info.
300 %
301 */
CloneStringInfo(const StringInfo * string_info)302 MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
303 {
304   StringInfo
305     *clone_info;
306 
307   assert(string_info != (StringInfo *) NULL);
308   assert(string_info->signature == MagickCoreSignature);
309   clone_info=AcquireStringInfo(string_info->length);
310   (void) CloneString(&clone_info->path,string_info->path);
311   (void) CloneString(&clone_info->name,string_info->name);
312   if (string_info->length != 0)
313     (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
314   return(clone_info);
315 }
316 
317 /*
318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319 %                                                                             %
320 %                                                                             %
321 %                                                                             %
322 %   C o m p a r e S t r i n g I n f o                                         %
323 %                                                                             %
324 %                                                                             %
325 %                                                                             %
326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
327 %
328 %  CompareStringInfo() compares the two datums target and source.  It returns
329 %  an integer less than, equal to, or greater than zero if target is found,
330 %  respectively, to be less than, to match, or be greater than source.
331 %
332 %  The format of the CompareStringInfo method is:
333 %
334 %      int CompareStringInfo(const StringInfo *target,const StringInfo *source)
335 %
336 %  A description of each parameter follows:
337 %
338 %    o target: the target string.
339 %
340 %    o source: the source string.
341 %
342 */
343 
CompareStringInfo(const StringInfo * target,const StringInfo * source)344 MagickExport int CompareStringInfo(const StringInfo *target,
345   const StringInfo *source)
346 {
347   int
348     status;
349 
350   assert(target != (StringInfo *) NULL);
351   assert(target->signature == MagickCoreSignature);
352   assert(source != (StringInfo *) NULL);
353   assert(source->signature == MagickCoreSignature);
354   status=memcmp(target->datum,source->datum,MagickMin(target->length,
355     source->length));
356   if (status != 0)
357     return(status);
358   if (target->length == source->length)
359     return(0);
360   return(target->length < source->length ? -1 : 1);
361 }
362 
363 /*
364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
365 %                                                                             %
366 %                                                                             %
367 %                                                                             %
368 %   C o n c a t e n a t e M a g i c k S t r i n g                             %
369 %                                                                             %
370 %                                                                             %
371 %                                                                             %
372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
373 %
374 %  ConcatenateMagickString() concatenates the source string to the destination
375 %  string.  The destination buffer is always null-terminated even if the
376 %  string must be truncated.
377 %
378 %  The format of the ConcatenateMagickString method is:
379 %
380 %      size_t ConcatenateMagickString(char *magick_restrict destination,
381 %        const char *magick_restrict source,const size_t length)
382 %
383 %  A description of each parameter follows:
384 %
385 %    o destination: the destination string.
386 %
387 %    o source: the source string.
388 %
389 %    o length: the length of the destination string.
390 %
391 */
ConcatenateMagickString(char * magick_restrict destination,const char * magick_restrict source,const size_t length)392 MagickExport size_t ConcatenateMagickString(char *magick_restrict destination,
393   const char *magick_restrict source,const size_t length)
394 {
395   char
396     *magick_restrict q;
397 
398   const char
399     *magick_restrict p;
400 
401   size_t
402     i;
403 
404   size_t
405     count;
406 
407   assert(destination != (char *) NULL);
408   assert(source != (const char *) NULL);
409   assert(length >= 1);
410   p=source;
411   q=destination;
412   i=length;
413   while ((i-- != 0) && (*q != '\0'))
414     q++;
415   count=(size_t) (q-destination);
416   i=length-count;
417   if (i == 0)
418     return(count+strlen(p));
419   while (*p != '\0')
420   {
421     if (i != 1)
422       {
423         *q++=(*p);
424         i--;
425       }
426     p++;
427   }
428   *q='\0';
429   return(count+(p-source));
430 }
431 
432 /*
433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434 %                                                                             %
435 %                                                                             %
436 %                                                                             %
437 %   C o n c a t e n a t e S t r i n g                                         %
438 %                                                                             %
439 %                                                                             %
440 %                                                                             %
441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
442 %
443 %  ConcatenateString() appends a copy of string source, including the
444 %  terminating null character, to the end of string destination.
445 %
446 %  The format of the ConcatenateString method is:
447 %
448 %      MagickBooleanType ConcatenateString(char **magick_restrict destination,
449 %        const char *magick_restrict source)
450 %
451 %  A description of each parameter follows:
452 %
453 %    o destination:  A pointer to a character string.
454 %
455 %    o source: A character string.
456 %
457 */
ConcatenateString(char ** magick_restrict destination,const char * magick_restrict source)458 MagickExport MagickBooleanType ConcatenateString(
459   char **magick_restrict destination,const char *magick_restrict source)
460 {
461   size_t
462     destination_length,
463     length,
464     source_length;
465 
466   assert(destination != (char **) NULL);
467   if (source == (const char *) NULL)
468     return(MagickTrue);
469   if (*destination == (char *) NULL)
470     {
471       *destination=AcquireString(source);
472       return(MagickTrue);
473     }
474   destination_length=strlen(*destination);
475   source_length=strlen(source);
476   length=destination_length;
477   if (~length < source_length)
478     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
479   length+=source_length;
480   if (~length < MagickPathExtent)
481     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
482   *destination=(char *) ResizeQuantumMemory(*destination,
483     OverAllocateMemory(length+MagickPathExtent),sizeof(**destination));
484   if (*destination == (char *) NULL)
485     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
486   if (source_length != 0)
487     (void) memcpy((*destination)+destination_length,source,source_length);
488   (*destination)[length]='\0';
489   return(MagickTrue);
490 }
491 
492 /*
493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
494 %                                                                             %
495 %                                                                             %
496 %                                                                             %
497 %   C o n c a t e n a t e S t r i n g I n f o                                 %
498 %                                                                             %
499 %                                                                             %
500 %                                                                             %
501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
502 %
503 %  ConcatenateStringInfo() concatenates the source string to the destination
504 %  string.
505 %
506 %  The format of the ConcatenateStringInfo method is:
507 %
508 %      void ConcatenateStringInfo(StringInfo *string_info,
509 %        const StringInfo *source)
510 %
511 %  A description of each parameter follows:
512 %
513 %    o string_info: the string info.
514 %
515 %    o source: the source string.
516 %
517 */
ConcatenateStringInfo(StringInfo * string_info,const StringInfo * source)518 MagickExport void ConcatenateStringInfo(StringInfo *string_info,
519   const StringInfo *source)
520 {
521   size_t
522     length;
523 
524   assert(string_info != (StringInfo *) NULL);
525   assert(string_info->signature == MagickCoreSignature);
526   assert(source != (const StringInfo *) NULL);
527   length=string_info->length;
528   if (~length < source->length)
529     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
530   length+=source->length;
531   if (~length < MagickPathExtent)
532     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
533   if (string_info->datum == (unsigned char *) NULL)
534     string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
535       MagickPathExtent,sizeof(*string_info->datum));
536   else
537     string_info->datum=(unsigned char *) ResizeQuantumMemory(
538       string_info->datum,OverAllocateMemory(length+MagickPathExtent),
539       sizeof(*string_info->datum));
540   if (string_info->datum == (unsigned char *) NULL)
541     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
542   (void) memcpy(string_info->datum+string_info->length,source->datum,source->length);
543   string_info->length=length;
544 }
545 
546 /*
547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
548 %                                                                             %
549 %                                                                             %
550 %                                                                             %
551 %   C o n f i g u r e F i l e T o S t r i n g I n f o                         %
552 %                                                                             %
553 %                                                                             %
554 %                                                                             %
555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
556 %
557 %  ConfigureFileToStringInfo() returns the contents of a configure file as a
558 %  string.
559 %
560 %  The format of the ConfigureFileToStringInfo method is:
561 %
562 %      StringInfo *ConfigureFileToStringInfo(const char *filename)
563 %        ExceptionInfo *exception)
564 %
565 %  A description of each parameter follows:
566 %
567 %    o filename: the filename.
568 %
569 */
ConfigureFileToStringInfo(const char * filename)570 MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
571 {
572   char
573     *string;
574 
575   int
576     file;
577 
578   MagickOffsetType
579     offset;
580 
581   size_t
582     length;
583 
584   StringInfo
585     *string_info;
586 
587   void
588     *map;
589 
590   assert(filename != (const char *) NULL);
591   file=open_utf8(filename,O_RDONLY | O_BINARY,0);
592   if (file == -1)
593     return((StringInfo *) NULL);
594   offset=(MagickOffsetType) lseek(file,0,SEEK_END);
595   if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
596     {
597       file=close(file)-1;
598       return((StringInfo *) NULL);
599     }
600   length=(size_t) offset;
601   string=(char *) NULL;
602   if (~length >= (MagickPathExtent-1))
603     string=(char *) AcquireQuantumMemory(length+MagickPathExtent,
604       sizeof(*string));
605   if (string == (char *) NULL)
606     {
607       file=close(file)-1;
608       return((StringInfo *) NULL);
609     }
610   map=MapBlob(file,ReadMode,0,length);
611   if (map != (void *) NULL)
612     {
613       (void) memcpy(string,map,length);
614       (void) UnmapBlob(map,length);
615     }
616   else
617     {
618       size_t
619         i;
620 
621       ssize_t
622         count;
623 
624       (void) lseek(file,0,SEEK_SET);
625       for (i=0; i < length; i+=count)
626       {
627         count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
628           MAGICK_SSIZE_MAX));
629         if (count <= 0)
630           {
631             count=0;
632             if (errno != EINTR)
633               break;
634           }
635       }
636       if (i < length)
637         {
638           file=close(file)-1;
639           string=DestroyString(string);
640           return((StringInfo *) NULL);
641         }
642     }
643   string[length]='\0';
644   file=close(file)-1;
645   string_info=AcquireStringInfoContainer();
646   string_info->path=ConstantString(filename);
647   string_info->length=length;
648   string_info->datum=(unsigned char *) string;
649   return(string_info);
650 }
651 
652 /*
653 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
654 %                                                                             %
655 %                                                                             %
656 %                                                                             %
657 %   C o n s t a n t S t r i n g                                               %
658 %                                                                             %
659 %                                                                             %
660 %                                                                             %
661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
662 %
663 %  ConstantString() allocates exactly the needed memory for a string and
664 %  copies the source string to that memory location.  A NULL string pointer
665 %  will allocate an empty string containing just the NUL character.
666 %
667 %  When finished the string should be freed using DestoryString()
668 %
669 %  The format of the ConstantString method is:
670 %
671 %      char *ConstantString(const char *source)
672 %
673 %  A description of each parameter follows:
674 %
675 %    o source: A character string.
676 %
677 */
ConstantString(const char * source)678 MagickExport char *ConstantString(const char *source)
679 {
680   char
681     *destination;
682 
683   size_t
684     length;
685 
686   length=0;
687   if (source != (char *) NULL)
688     length+=strlen(source);
689   destination=(char *) NULL;
690   if (~length >= 1UL)
691     destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
692   if (destination == (char *) NULL)
693     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
694   if (source != (char *) NULL)
695     (void) memcpy(destination,source,length*sizeof(*destination));
696   destination[length]='\0';
697   return(destination);
698 }
699 
700 /*
701 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
702 %                                                                             %
703 %                                                                             %
704 %                                                                             %
705 %   C o p y M a g i c k S t r i n g                                           %
706 %                                                                             %
707 %                                                                             %
708 %                                                                             %
709 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710 %
711 %  CopyMagickString() copies the source string to the destination string, with
712 %  out exceeding the given pre-declared length.
713 %
714 %  The destination buffer is always null-terminated even if the string must be
715 %  truncated.  The return value is the length of the string.
716 %
717 %  The format of the CopyMagickString method is:
718 %
719 %      size_t CopyMagickString(const char *magick_restrict destination,
720 %        char *magick_restrict source,const size_t length)
721 %
722 %  A description of each parameter follows:
723 %
724 %    o destination: the destination string.
725 %
726 %    o source: the source string.
727 %
728 %    o length: the length of the destination string.
729 %
730 */
CopyMagickString(char * magick_restrict destination,const char * magick_restrict source,const size_t length)731 MagickExport size_t CopyMagickString(char *magick_restrict destination,
732   const char *magick_restrict source,const size_t length)
733 {
734   char
735     *magick_restrict q;
736 
737   const char
738     *magick_restrict p;
739 
740   size_t
741     n;
742 
743   p=source;
744   q=destination;
745   for (n=length; n > 4; n-=4)
746   {
747     if (((*q++)=(*p++)) == '\0')
748       return((size_t) (p-source-1));
749     if (((*q++)=(*p++)) == '\0')
750       return((size_t) (p-source-1));
751     if (((*q++)=(*p++)) == '\0')
752       return((size_t) (p-source-1));
753     if (((*q++)=(*p++)) == '\0')
754       return((size_t) (p-source-1));
755   }
756   if (length != 0)
757     {
758       while (--n != 0)
759         if (((*q++)=(*p++)) == '\0')
760           return((size_t) (p-source-1));
761       *q='\0';
762     }
763   return((size_t) (p-source));
764 }
765 
766 /*
767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
768 %                                                                             %
769 %                                                                             %
770 %                                                                             %
771 %   D e s t r o y S t r i n g                                                 %
772 %                                                                             %
773 %                                                                             %
774 %                                                                             %
775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
776 %
777 %  DestroyString() destroys memory associated with a string.
778 %
779 %  The format of the DestroyString method is:
780 %
781 %      char *DestroyString(char *string)
782 %
783 %  A description of each parameter follows:
784 %
785 %    o string: the string.
786 %
787 */
DestroyString(char * string)788 MagickExport char *DestroyString(char *string)
789 {
790   return((char *) RelinquishMagickMemory(string));
791 }
792 
793 /*
794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795 %                                                                             %
796 %                                                                             %
797 %                                                                             %
798 %   D e s t r o y S t r i n g I n f o                                         %
799 %                                                                             %
800 %                                                                             %
801 %                                                                             %
802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
803 %
804 %  DestroyStringInfo() destroys memory associated with the StringInfo structure.
805 %
806 %  The format of the DestroyStringInfo method is:
807 %
808 %      StringInfo *DestroyStringInfo(StringInfo *string_info)
809 %
810 %  A description of each parameter follows:
811 %
812 %    o string_info: the string info.
813 %
814 */
DestroyStringInfo(StringInfo * string_info)815 MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
816 {
817   assert(string_info != (StringInfo *) NULL);
818   assert(string_info->signature == MagickCoreSignature);
819   if (string_info->datum != (unsigned char *) NULL)
820     string_info->datum=(unsigned char *) RelinquishMagickMemory(
821       string_info->datum);
822   if (string_info->name != (char *) NULL)
823     string_info->name=DestroyString(string_info->name);
824   if (string_info->path != (char *) NULL)
825     string_info->path=DestroyString(string_info->path);
826   string_info->signature=(~MagickCoreSignature);
827   string_info=(StringInfo *) RelinquishMagickMemory(string_info);
828   return(string_info);
829 }
830 
831 /*
832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
833 %                                                                             %
834 %                                                                             %
835 %                                                                             %
836 %   D e s t r o y S t r i n g L i s t                                         %
837 %                                                                             %
838 %                                                                             %
839 %                                                                             %
840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
841 %
842 %  DestroyStringList() zeros memory associated with a string list.
843 %
844 %  The format of the DestroyStringList method is:
845 %
846 %      char **DestroyStringList(char **list)
847 %
848 %  A description of each parameter follows:
849 %
850 %    o list: the string list.
851 %
852 */
DestroyStringList(char ** list)853 MagickExport char **DestroyStringList(char **list)
854 {
855   ssize_t
856     i;
857 
858   assert(list != (char **) NULL);
859   for (i=0; list[i] != (char *) NULL; i++)
860     list[i]=DestroyString(list[i]);
861   list=(char **) RelinquishMagickMemory(list);
862   return(list);
863 }
864 
865 /*
866 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
867 %                                                                             %
868 %                                                                             %
869 %                                                                             %
870 %   E s c a p e S t r i n g                                                   %
871 %                                                                             %
872 %                                                                             %
873 %                                                                             %
874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
875 %
876 %  EscapeString() allocates memory for a backslash-escaped version of a
877 %  source text string, copies the escaped version of the text to that
878 %  memory location while adding backslash characters, and returns the
879 %  escaped string.
880 %
881 %  The format of the EscapeString method is:
882 %
883 %      char *EscapeString(const char *source,const char escape)
884 %
885 %  A description of each parameter follows:
886 %
887 %    o allocate_string:  Method EscapeString returns the escaped string.
888 %
889 %    o source: A character string.
890 %
891 %    o escape: the quoted string termination character to escape (e.g. '"').
892 %
893 */
EscapeString(const char * source,const char escape)894 MagickExport char *EscapeString(const char *source,const char escape)
895 {
896   char
897     *destination;
898 
899   char
900     *q;
901 
902   const char
903     *p;
904 
905   size_t
906     length;
907 
908   assert(source != (const char *) NULL);
909   length=0;
910   for (p=source; *p != '\0'; p++)
911   {
912     if ((*p == '\\') || (*p == escape))
913       {
914         if (~length < 1)
915           ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
916         length++;
917       }
918     length++;
919   }
920   destination=(char *) NULL;
921   if (~length >= (MagickPathExtent-1))
922     destination=(char *) AcquireQuantumMemory(length+MagickPathExtent,
923       sizeof(*destination));
924   if (destination == (char *) NULL)
925     ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
926   *destination='\0';
927   q=destination;
928   for (p=source; *p != '\0'; p++)
929   {
930     if ((*p == '\\') || (*p == escape))
931       *q++='\\';
932     *q++=(*p);
933   }
934   *q='\0';
935   return(destination);
936 }
937 
938 /*
939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
940 %                                                                             %
941 %                                                                             %
942 %                                                                             %
943 %   F i l e T o S t r i n g                                                   %
944 %                                                                             %
945 %                                                                             %
946 %                                                                             %
947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
948 %
949 %  FileToString() returns the contents of a file as a string.
950 %
951 %  The format of the FileToString method is:
952 %
953 %      char *FileToString(const char *filename,const size_t extent,
954 %        ExceptionInfo *exception)
955 %
956 %  A description of each parameter follows:
957 %
958 %    o filename: the filename.
959 %
960 %    o extent: Maximum length of the string.
961 %
962 %    o exception: return any errors or warnings in this structure.
963 %
964 */
FileToString(const char * filename,const size_t extent,ExceptionInfo * exception)965 MagickExport char *FileToString(const char *filename,const size_t extent,
966   ExceptionInfo *exception)
967 {
968   size_t
969     length;
970 
971   assert(filename != (const char *) NULL);
972   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
973   assert(exception != (ExceptionInfo *) NULL);
974   return((char *) FileToBlob(filename,extent,&length,exception));
975 }
976 
977 /*
978 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
979 %                                                                             %
980 %                                                                             %
981 %                                                                             %
982 %   F i l e T o S t r i n g I n f o                                           %
983 %                                                                             %
984 %                                                                             %
985 %                                                                             %
986 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
987 %
988 %  FileToStringInfo() returns the contents of a file as a string.
989 %
990 %  The format of the FileToStringInfo method is:
991 %
992 %      StringInfo *FileToStringInfo(const char *filename,const size_t extent,
993 %        ExceptionInfo *exception)
994 %
995 %  A description of each parameter follows:
996 %
997 %    o filename: the filename.
998 %
999 %    o extent: Maximum length of the string.
1000 %
1001 %    o exception: return any errors or warnings in this structure.
1002 %
1003 */
FileToStringInfo(const char * filename,const size_t extent,ExceptionInfo * exception)1004 MagickExport StringInfo *FileToStringInfo(const char *filename,
1005   const size_t extent,ExceptionInfo *exception)
1006 {
1007   StringInfo
1008     *string_info;
1009 
1010   assert(filename != (const char *) NULL);
1011   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1012   assert(exception != (ExceptionInfo *) NULL);
1013   string_info=AcquireStringInfoContainer();
1014   string_info->path=ConstantString(filename);
1015   string_info->datum=(unsigned char *) FileToBlob(filename,extent,
1016     &string_info->length,exception);
1017   if (string_info->datum == (unsigned char *) NULL)
1018     {
1019       string_info=DestroyStringInfo(string_info);
1020       return((StringInfo *) NULL);
1021     }
1022   return(string_info);
1023 }
1024 
1025 /*
1026 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1027 %                                                                             %
1028 %                                                                             %
1029 %                                                                             %
1030 %  F o r m a t M a g i c k S i z e                                            %
1031 %                                                                             %
1032 %                                                                             %
1033 %                                                                             %
1034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1035 %
1036 %  FormatMagickSize() converts a size to a human readable format, for example,
1037 %  14k, 234m, 2.7g, or 3.0t.  Scaling is done by repetitively dividing by
1038 %  1000.
1039 %
1040 %  The format of the FormatMagickSize method is:
1041 %
1042 %      ssize_t FormatMagickSize(const MagickSizeType size,const char *suffix,
1043 %        const size_t length,char *format)
1044 %
1045 %  A description of each parameter follows:
1046 %
1047 %    o size:  convert this size to a human readable format.
1048 %
1049 %    o bi:  use power of two rather than power of ten.
1050 %
1051 %    o suffix:  append suffix, typically B or P.
1052 %
1053 %    o length: the maximum length of the string.
1054 %
1055 %    o format:  human readable format.
1056 %
1057 */
FormatMagickSize(const MagickSizeType size,const MagickBooleanType bi,const char * suffix,const size_t length,char * format)1058 MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
1059   const MagickBooleanType bi,const char *suffix,const size_t length,
1060   char *format)
1061 {
1062   char
1063     p[MagickPathExtent],
1064     q[MagickPathExtent];
1065 
1066   const char
1067     **units;
1068 
1069   double
1070     bytes,
1071     extent;
1072 
1073   ssize_t
1074     i;
1075 
1076   ssize_t
1077     count;
1078 
1079   static const char
1080     *bi_units[] =
1081     {
1082       "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
1083     },
1084     *traditional_units[] =
1085     {
1086       "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
1087     };
1088 
1089   bytes=1000.0;
1090   units=traditional_units;
1091   if (bi != MagickFalse)
1092     {
1093       bytes=1024.0;
1094       units=bi_units;
1095     }
1096   extent=(double) size;
1097   (void) FormatLocaleString(p,MagickPathExtent,"%.*g",GetMagickPrecision(),
1098     extent);
1099   (void) FormatLocaleString(q,MagickPathExtent,"%.20g",extent);
1100   if (strtod(p,(char **) NULL) == strtod(q,(char **) NULL))
1101     {
1102       if (suffix == (const char *) NULL)
1103         count=FormatLocaleString(format,length,"%.20g%s",extent,units[0]);
1104       else
1105         count=FormatLocaleString(format,length,"%.20g%s%s",extent,units[0],
1106           suffix);
1107       return(count);
1108     }
1109   for (i=0; (extent >= bytes) && (units[i+1] != (const char *) NULL); i++)
1110     extent/=bytes;
1111   if (suffix == (const char *) NULL)
1112     count=FormatLocaleString(format,length,"%.*g%s",GetMagickPrecision(),
1113       extent,units[i]);
1114   else
1115     count=FormatLocaleString(format,length,"%.*g%s%s",GetMagickPrecision(),
1116       extent,units[i],suffix);
1117   return(count);
1118 }
1119 
1120 /*
1121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1122 %                                                                             %
1123 %                                                                             %
1124 %                                                                             %
1125 %   G e t E n v i r o n m e n t V a l u e                                     %
1126 %                                                                             %
1127 %                                                                             %
1128 %                                                                             %
1129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1130 %
1131 %  GetEnvironmentValue() returns the environment string that matches the
1132 %  specified name.
1133 %
1134 %  The format of the GetEnvironmentValue method is:
1135 %
1136 %      char *GetEnvironmentValue(const char *name)
1137 %
1138 %  A description of each parameter follows:
1139 %
1140 %    o name: the environment name.
1141 %
1142 */
GetEnvironmentValue(const char * name)1143 MagickExport char *GetEnvironmentValue(const char *name)
1144 {
1145   const char
1146     *environment;
1147 
1148   environment=getenv(name);
1149   if (environment == (const char *) NULL)
1150     return((char *) NULL);
1151   return(ConstantString(environment));
1152 }
1153 
1154 /*
1155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1156 %                                                                             %
1157 %                                                                             %
1158 %                                                                             %
1159 %   G e t S t r i n g I n f o D a t u m                                       %
1160 %                                                                             %
1161 %                                                                             %
1162 %                                                                             %
1163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1164 %
1165 %  GetStringInfoDatum() returns the datum associated with the string.
1166 %
1167 %  The format of the GetStringInfoDatum method is:
1168 %
1169 %      unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1170 %
1171 %  A description of each parameter follows:
1172 %
1173 %    o string_info: the string info.
1174 %
1175 */
GetStringInfoDatum(const StringInfo * string_info)1176 MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1177 {
1178   assert(string_info != (StringInfo *) NULL);
1179   assert(string_info->signature == MagickCoreSignature);
1180   return(string_info->datum);
1181 }
1182 
1183 /*
1184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1185 %                                                                             %
1186 %                                                                             %
1187 %                                                                             %
1188 %   G e t S t r i n g I n f o L e n g t h                                     %
1189 %                                                                             %
1190 %                                                                             %
1191 %                                                                             %
1192 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1193 %
1194 %  GetStringInfoLength() returns the string length.
1195 %
1196 %  The format of the GetStringInfoLength method is:
1197 %
1198 %      size_t GetStringInfoLength(const StringInfo *string_info)
1199 %
1200 %  A description of each parameter follows:
1201 %
1202 %    o string_info: the string info.
1203 %
1204 */
GetStringInfoLength(const StringInfo * string_info)1205 MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1206 {
1207   assert(string_info != (StringInfo *) NULL);
1208   assert(string_info->signature == MagickCoreSignature);
1209   return(string_info->length);
1210 }
1211 
1212 /*
1213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1214 %                                                                             %
1215 %                                                                             %
1216 %                                                                             %
1217 %   G e t S t r i n g I n f o N a m e                                         %
1218 %                                                                             %
1219 %                                                                             %
1220 %                                                                             %
1221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1222 %
1223 %  GetStringInfoName() returns the name associated with the string.
1224 %
1225 %  The format of the GetStringInfoName method is:
1226 %
1227 %      const char *GetStringInfoName(const StringInfo *string_info)
1228 %
1229 %  A description of each parameter follows:
1230 %
1231 %    o string_info: the string info.
1232 %
1233 */
GetStringInfoName(const StringInfo * string_info)1234 MagickExport const char *GetStringInfoName(const StringInfo *string_info)
1235 {
1236   assert(string_info != (StringInfo *) NULL);
1237   assert(string_info->signature == MagickCoreSignature);
1238   return(string_info->name);
1239 }
1240 
1241 /*
1242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1243 %                                                                             %
1244 %                                                                             %
1245 %                                                                             %
1246 %   G e t S t r i n g I n f o P a t h                                         %
1247 %                                                                             %
1248 %                                                                             %
1249 %                                                                             %
1250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1251 %
1252 %  GetStringInfoPath() returns the path associated with the string.
1253 %
1254 %  The format of the GetStringInfoPath method is:
1255 %
1256 %      const char *GetStringInfoPath(const StringInfo *string_info)
1257 %
1258 %  A description of each parameter follows:
1259 %
1260 %    o string_info: the string info.
1261 %
1262 */
GetStringInfoPath(const StringInfo * string_info)1263 MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1264 {
1265   assert(string_info != (StringInfo *) NULL);
1266   assert(string_info->signature == MagickCoreSignature);
1267   return(string_info->path);
1268 }
1269 
1270 /*
1271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1272 %                                                                             %
1273 %                                                                             %
1274 %                                                                             %
1275 +   I n t e r p r e t S i P r e f i x V a l u e                               %
1276 %                                                                             %
1277 %                                                                             %
1278 %                                                                             %
1279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1280 %
1281 %  InterpretSiPrefixValue() converts the initial portion of the string to a
1282 %  double representation.  It also recognizes SI prefixes (e.g. B, KB, MiB,
1283 %  etc.).
1284 %
1285 %  The format of the InterpretSiPrefixValue method is:
1286 %
1287 %      double InterpretSiPrefixValue(const char *value,char **sentinal)
1288 %
1289 %  A description of each parameter follows:
1290 %
1291 %    o value: the string value.
1292 %
1293 %    o sentinal:  if sentinal is not NULL, return a pointer to the character
1294 %      after the last character used in the conversion.
1295 %
1296 */
InterpretSiPrefixValue(const char * magick_restrict string,char ** magick_restrict sentinal)1297 MagickExport double InterpretSiPrefixValue(const char *magick_restrict string,
1298   char **magick_restrict sentinal)
1299 {
1300   char
1301     *q;
1302 
1303   double
1304     value;
1305 
1306   value=InterpretLocaleValue(string,&q);
1307   if (q != string)
1308     {
1309       if ((*q >= 'E') && (*q <= 'z'))
1310         {
1311           double
1312             e;
1313 
1314           switch ((int) ((unsigned char) *q))
1315           {
1316             case 'y': e=(-24.0); break;
1317             case 'z': e=(-21.0); break;
1318             case 'a': e=(-18.0); break;
1319             case 'f': e=(-15.0); break;
1320             case 'p': e=(-12.0); break;
1321             case 'n': e=(-9.0); break;
1322             case 'u': e=(-6.0); break;
1323             case 'm': e=(-3.0); break;
1324             case 'c': e=(-2.0); break;
1325             case 'd': e=(-1.0); break;
1326             case 'h': e=2.0; break;
1327             case 'k': e=3.0; break;
1328             case 'K': e=3.0; break;
1329             case 'M': e=6.0; break;
1330             case 'G': e=9.0; break;
1331             case 'T': e=12.0; break;
1332             case 'P': e=15.0; break;
1333             case 'E': e=18.0; break;
1334             case 'Z': e=21.0; break;
1335             case 'Y': e=24.0; break;
1336             default: e=0.0; break;
1337           }
1338           if (e >= MagickEpsilon)
1339             {
1340               if (q[1] == 'i')
1341                 {
1342                   value*=pow(2.0,e/0.3);
1343                   q+=2;
1344                 }
1345               else
1346                 {
1347                   value*=pow(10.0,e);
1348                   q++;
1349                 }
1350             }
1351         }
1352       if ((*q == 'B') || (*q == 'P'))
1353         q++;
1354     }
1355   if (sentinal != (char **) NULL)
1356     *sentinal=q;
1357   return(value);
1358 }
1359 
1360 /*
1361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1362 %                                                                             %
1363 %                                                                             %
1364 %                                                                             %
1365 %   I s S t r i n g T r u e                                                   %
1366 %                                                                             %
1367 %                                                                             %
1368 %                                                                             %
1369 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1370 %
1371 %  IsStringTrue() returns MagickTrue if the value is "true", "on", "yes" or
1372 %  "1". Any other string or undefined returns MagickFalse.
1373 %
1374 %  Typically this is used to look at strings (options or artifacts) which
1375 %  has a default value of "false", when not defined.
1376 %
1377 %  The format of the IsStringTrue method is:
1378 %
1379 %      MagickBooleanType IsStringTrue(const char *value)
1380 %
1381 %  A description of each parameter follows:
1382 %
1383 %    o value: Specifies a pointer to a character array.
1384 %
1385 */
IsStringTrue(const char * value)1386 MagickExport MagickBooleanType IsStringTrue(const char *value)
1387 {
1388   if (value == (const char *) NULL)
1389     return(MagickFalse);
1390   if (LocaleCompare(value,"true") == 0)
1391     return(MagickTrue);
1392   if (LocaleCompare(value,"on") == 0)
1393     return(MagickTrue);
1394   if (LocaleCompare(value,"yes") == 0)
1395     return(MagickTrue);
1396   if (LocaleCompare(value,"1") == 0)
1397     return(MagickTrue);
1398   return(MagickFalse);
1399 }
1400 
1401 /*
1402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1403 %                                                                             %
1404 %                                                                             %
1405 %                                                                             %
1406 %   I s S t r i n g F a l s e                                                 %
1407 %                                                                             %
1408 %                                                                             %
1409 %                                                                             %
1410 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1411 %
1412 %  IsStringFalse() returns MagickTrue if the value is "false", "off", "no" or
1413 %  "0". Any other string or undefined returns MagickFalse.
1414 %
1415 %  Typically this is used to look at strings (options or artifacts) which
1416 %  has a default value of "true", when it has not been defined.
1417 %
1418 %  The format of the IsStringFalse method is:
1419 %
1420 %      MagickBooleanType IsStringFalse(const char *value)
1421 %
1422 %  A description of each parameter follows:
1423 %
1424 %    o value: Specifies a pointer to a character array.
1425 %
1426 */
IsStringFalse(const char * value)1427 MagickExport MagickBooleanType IsStringFalse(const char *value)
1428 {
1429   if (value == (const char *) NULL)
1430     return(MagickFalse);
1431   if (LocaleCompare(value,"false") == 0)
1432     return(MagickTrue);
1433   if (LocaleCompare(value,"off") == 0)
1434     return(MagickTrue);
1435   if (LocaleCompare(value,"no") == 0)
1436     return(MagickTrue);
1437   if (LocaleCompare(value,"0") == 0)
1438     return(MagickTrue);
1439   return(MagickFalse);
1440 }
1441 
1442 /*
1443 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1444 %                                                                             %
1445 %                                                                             %
1446 %                                                                             %
1447 %   P r i n t S t r i n g I n f o                                             %
1448 %                                                                             %
1449 %                                                                             %
1450 %                                                                             %
1451 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1452 %
1453 %  PrintStringInfo() prints the string.
1454 %
1455 %  The format of the PrintStringInfo method is:
1456 %
1457 %      void PrintStringInfo(FILE *file,const char *id,
1458 %        const StringInfo *string_info)
1459 %
1460 %  A description of each parameter follows:
1461 %
1462 %    o file: the file, typically stdout.
1463 %
1464 %    o id: the string id.
1465 %
1466 %    o string_info: the string info.
1467 %
1468 */
PrintStringInfo(FILE * file,const char * id,const StringInfo * string_info)1469 MagickExport void PrintStringInfo(FILE *file,const char *id,
1470   const StringInfo *string_info)
1471 {
1472   const char
1473     *p;
1474 
1475   size_t
1476     i,
1477     j;
1478 
1479   assert(id != (const char *) NULL);
1480   assert(string_info != (StringInfo *) NULL);
1481   assert(string_info->signature == MagickCoreSignature);
1482   p=(char *) string_info->datum;
1483   for (i=0; i < string_info->length; i++)
1484   {
1485     if (((int) ((unsigned char) *p) < 32) &&
1486         (isspace((int) ((unsigned char) *p)) == 0))
1487       break;
1488     p++;
1489   }
1490   (void) FormatLocaleFile(file,"%s(%.20g):\n",id,(double) string_info->length);
1491   if (i == string_info->length)
1492     {
1493       for (i=0; i < string_info->length; i++)
1494         (void) fputc(string_info->datum[i],file);
1495       (void) fputc('\n',file);
1496       return;
1497     }
1498   /*
1499     Convert string to a HEX list.
1500   */
1501   p=(char *) string_info->datum;
1502   for (i=0; i < string_info->length; i+=CharsPerLine)
1503   {
1504     (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (CharsPerLine*i));
1505     for (j=1; j <= MagickMin(string_info->length-i,CharsPerLine); j++)
1506     {
1507       (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
1508       if ((j % 0x04) == 0)
1509         (void) fputc(' ',file);
1510     }
1511     for ( ; j <= CharsPerLine; j++)
1512     {
1513       (void) fputc(' ',file);
1514       (void) fputc(' ',file);
1515       if ((j % 0x04) == 0)
1516         (void) fputc(' ',file);
1517     }
1518     (void) fputc(' ',file);
1519     for (j=1; j <= MagickMin(string_info->length-i,CharsPerLine); j++)
1520     {
1521       if (isprint((int) ((unsigned char) *p)) != 0)
1522         (void) fputc(*p,file);
1523       else
1524         (void) fputc('-',file);
1525       p++;
1526     }
1527     (void) fputc('\n',file);
1528   }
1529 }
1530 
1531 /*
1532 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1533 %                                                                             %
1534 %                                                                             %
1535 %                                                                             %
1536 %   R e s e t S t r i n g I n f o                                             %
1537 %                                                                             %
1538 %                                                                             %
1539 %                                                                             %
1540 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1541 %
1542 %  ResetStringInfo() reset the string to all null bytes.
1543 %
1544 %  The format of the ResetStringInfo method is:
1545 %
1546 %      void ResetStringInfo(StringInfo *string_info)
1547 %
1548 %  A description of each parameter follows:
1549 %
1550 %    o string_info: the string info.
1551 %
1552 */
ResetStringInfo(StringInfo * string_info)1553 MagickExport void ResetStringInfo(StringInfo *string_info)
1554 {
1555   assert(string_info != (StringInfo *) NULL);
1556   assert(string_info->signature == MagickCoreSignature);
1557   (void) memset(string_info->datum,0,string_info->length);
1558 }
1559 
1560 /*
1561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1562 %                                                                             %
1563 %                                                                             %
1564 %                                                                             %
1565 %   S a n t i z e S t r i n g                                                 %
1566 %                                                                             %
1567 %                                                                             %
1568 %                                                                             %
1569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1570 %
1571 %  SanitizeString() returns a new string with all characters removed except
1572 %  letters, digits and !#$%&'*+-=?^_`{|}~@.[].
1573 %
1574 %  Free the sanitized string with DestroyString().
1575 %
1576 %  The format of the SanitizeString method is:
1577 %
1578 %      char *SanitizeString(const char *source)
1579 %
1580 %  A description of each parameter follows:
1581 %
1582 %    o source: A character string.
1583 %
1584 */
SanitizeString(const char * source)1585 MagickExport char *SanitizeString(const char *source)
1586 {
1587   char
1588     *sanitize_source;
1589 
1590   const char
1591     *q;
1592 
1593   char
1594     *p;
1595 
1596   static char
1597     allowlist[] =
1598       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 "
1599       "$-_.+!*'(),{}|\\^~[]`\"><#%;/?:@&=";
1600 
1601   sanitize_source=AcquireString(source);
1602   p=sanitize_source;
1603   q=sanitize_source+strlen(sanitize_source);
1604   for (p+=strspn(p,allowlist); p != q; p+=strspn(p,allowlist))
1605     *p='_';
1606   return(sanitize_source);
1607 }
1608 
1609 /*
1610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1611 %                                                                             %
1612 %                                                                             %
1613 %                                                                             %
1614 %   S e t S t r i n g I n f o                                                 %
1615 %                                                                             %
1616 %                                                                             %
1617 %                                                                             %
1618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1619 %
1620 %  SetStringInfo() copies the source string to the destination string.
1621 %
1622 %  The format of the SetStringInfo method is:
1623 %
1624 %      void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1625 %
1626 %  A description of each parameter follows:
1627 %
1628 %    o string_info: the string info.
1629 %
1630 %    o source: the source string.
1631 %
1632 */
SetStringInfo(StringInfo * string_info,const StringInfo * source)1633 MagickExport void SetStringInfo(StringInfo *string_info,
1634   const StringInfo *source)
1635 {
1636   assert(string_info != (StringInfo *) NULL);
1637   assert(string_info->signature == MagickCoreSignature);
1638   assert(source != (StringInfo *) NULL);
1639   assert(source->signature == MagickCoreSignature);
1640   if (string_info->length == 0)
1641     return;
1642   (void) memset(string_info->datum,0,string_info->length);
1643   (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1644     source->length));
1645 }
1646 
1647 /*
1648 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1649 %                                                                             %
1650 %                                                                             %
1651 %                                                                             %
1652 %   S e t S t r i n g I n f o D a t u m                                       %
1653 %                                                                             %
1654 %                                                                             %
1655 %                                                                             %
1656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1657 %
1658 %  SetStringInfoDatum() copies bytes from the source string for the length of
1659 %  the destination string.
1660 %
1661 %  The format of the SetStringInfoDatum method is:
1662 %
1663 %      void SetStringInfoDatum(StringInfo *string_info,
1664 %        const unsigned char *source)
1665 %
1666 %  A description of each parameter follows:
1667 %
1668 %    o string_info: the string info.
1669 %
1670 %    o source: the source string.
1671 %
1672 */
SetStringInfoDatum(StringInfo * string_info,const unsigned char * source)1673 MagickExport void SetStringInfoDatum(StringInfo *string_info,
1674   const unsigned char *source)
1675 {
1676   assert(string_info != (StringInfo *) NULL);
1677   assert(string_info->signature == MagickCoreSignature);
1678   if (string_info->length != 0)
1679     (void) memcpy(string_info->datum,source,string_info->length);
1680 }
1681 
1682 /*
1683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1684 %                                                                             %
1685 %                                                                             %
1686 %                                                                             %
1687 %   S e t S t r i n g I n f o L e n g t h                                     %
1688 %                                                                             %
1689 %                                                                             %
1690 %                                                                             %
1691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1692 %
1693 %  SetStringInfoLength() set the string length to the specified value.
1694 %
1695 %  The format of the SetStringInfoLength method is:
1696 %
1697 %      void SetStringInfoLength(StringInfo *string_info,const size_t length)
1698 %
1699 %  A description of each parameter follows:
1700 %
1701 %    o string_info: the string info.
1702 %
1703 %    o length: the string length.
1704 %
1705 */
SetStringInfoLength(StringInfo * string_info,const size_t length)1706 MagickExport void SetStringInfoLength(StringInfo *string_info,
1707   const size_t length)
1708 {
1709   assert(string_info != (StringInfo *) NULL);
1710   assert(string_info->signature == MagickCoreSignature);
1711   if (string_info->length == length)
1712     return;
1713   if (~length < MagickPathExtent)
1714     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1715   string_info->length=length;
1716   if (string_info->datum == (unsigned char *) NULL)
1717     string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1718       MagickPathExtent,sizeof(*string_info->datum));
1719   else
1720     string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1721       length+MagickPathExtent,sizeof(*string_info->datum));
1722   if (string_info->datum == (unsigned char *) NULL)
1723     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1724 }
1725 
1726 /*
1727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1728 %                                                                             %
1729 %                                                                             %
1730 %                                                                             %
1731 %   S e t S t r i n g I n f o N a m e                                         %
1732 %                                                                             %
1733 %                                                                             %
1734 %                                                                             %
1735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1736 %
1737 %  SetStringInfoName() sets the name associated with the string.
1738 %
1739 %  The format of the SetStringInfoName method is:
1740 %
1741 %      void SetStringInfoName(StringInfo *string_info,const char *name)
1742 %
1743 %  A description of each parameter follows:
1744 %
1745 %    o string_info: the string info.
1746 %
1747 %    o name: the name.
1748 %
1749 */
SetStringInfoName(StringInfo * string_info,const char * name)1750 MagickExport void SetStringInfoName(StringInfo *string_info,const char *name)
1751 {
1752   assert(string_info != (StringInfo *) NULL);
1753   assert(string_info->signature == MagickCoreSignature);
1754   assert(name != (const char *) NULL);
1755   string_info->name=ConstantString(name);
1756 }
1757 
1758 /*
1759 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1760 %                                                                             %
1761 %                                                                             %
1762 %                                                                             %
1763 %   S e t S t r i n g I n f o P a t h                                         %
1764 %                                                                             %
1765 %                                                                             %
1766 %                                                                             %
1767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1768 %
1769 %  SetStringInfoPath() sets the path associated with the string.
1770 %
1771 %  The format of the SetStringInfoPath method is:
1772 %
1773 %      void SetStringInfoPath(StringInfo *string_info,const char *path)
1774 %
1775 %  A description of each parameter follows:
1776 %
1777 %    o string_info: the string info.
1778 %
1779 %    o path: the path.
1780 %
1781 */
SetStringInfoPath(StringInfo * string_info,const char * path)1782 MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1783 {
1784   assert(string_info != (StringInfo *) NULL);
1785   assert(string_info->signature == MagickCoreSignature);
1786   assert(path != (const char *) NULL);
1787   string_info->path=ConstantString(path);
1788 }
1789 
1790 /*
1791 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1792 %                                                                             %
1793 %                                                                             %
1794 %                                                                             %
1795 %   S p l i t S t r i n g I n f o                                             %
1796 %                                                                             %
1797 %                                                                             %
1798 %                                                                             %
1799 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1800 %
1801 %  SplitStringInfo() splits a string into two and returns it.
1802 %
1803 %  The format of the SplitStringInfo method is:
1804 %
1805 %      StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1806 %
1807 %  A description of each parameter follows:
1808 %
1809 %    o string_info: the string info.
1810 %
1811 */
SplitStringInfo(StringInfo * string_info,const size_t offset)1812 MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1813   const size_t offset)
1814 {
1815   StringInfo
1816     *split_info;
1817 
1818   assert(string_info != (StringInfo *) NULL);
1819   assert(string_info->signature == MagickCoreSignature);
1820   if (offset > string_info->length)
1821     return((StringInfo *) NULL);
1822   split_info=AcquireStringInfo(offset);
1823   SetStringInfo(split_info,string_info);
1824   (void) memmove(string_info->datum,string_info->datum+offset,
1825     string_info->length-offset+MagickPathExtent);
1826   SetStringInfoLength(string_info,string_info->length-offset);
1827   return(split_info);
1828 }
1829 
1830 /*
1831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1832 %                                                                             %
1833 %                                                                             %
1834 %                                                                             %
1835 %   S t r i n g I n f o T o D i g e s t                                       %
1836 %                                                                             %
1837 %                                                                             %
1838 %                                                                             %
1839 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1840 %
1841 %  StringInfoToDigest() converts a string info string to a hex digest.
1842 %
1843 %  The format of the StringInfoToString method is:
1844 %
1845 %      char *StringInfoToDigest(const StringInfo *signature)
1846 %
1847 %  A description of each parameter follows:
1848 %
1849 %    o string_info: the string.
1850 %
1851 */
StringInfoToDigest(const StringInfo * signature)1852 MagickExport char *StringInfoToDigest(const StringInfo *signature)
1853 {
1854   char
1855     *digest;
1856 
1857   SignatureInfo
1858     *signature_info;
1859 
1860   signature_info=AcquireSignatureInfo();
1861   UpdateSignature(signature_info,signature);
1862   FinalizeSignature(signature_info);
1863   digest=StringInfoToHexString(GetSignatureDigest(signature_info));
1864   signature_info=DestroySignatureInfo(signature_info);
1865   return(digest);
1866 }
1867 
1868 /*
1869 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1870 %                                                                             %
1871 %                                                                             %
1872 %                                                                             %
1873 %   S t r i n g I n f o T o H e x S t r i n g                                 %
1874 %                                                                             %
1875 %                                                                             %
1876 %                                                                             %
1877 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1878 %
1879 %  StringInfoToHexString() converts a string info string to a C string.
1880 %
1881 %  The format of the StringInfoToHexString method is:
1882 %
1883 %      char *StringInfoToHexString(const StringInfo *string_info)
1884 %
1885 %  A description of each parameter follows:
1886 %
1887 %    o string_info: the string.
1888 %
1889 */
StringInfoToHexString(const StringInfo * string_info)1890 MagickExport char *StringInfoToHexString(const StringInfo *string_info)
1891 {
1892   char
1893     *string;
1894 
1895   const unsigned char
1896     *p;
1897 
1898   ssize_t
1899     i;
1900 
1901   unsigned char
1902     *q;
1903 
1904   size_t
1905     length;
1906 
1907   unsigned char
1908     hex_digits[16];
1909 
1910   length=string_info->length;
1911   if (~length < MagickPathExtent)
1912     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
1913   string=(char *) AcquireQuantumMemory(length+MagickPathExtent,2*
1914     sizeof(*string));
1915   if (string == (char *) NULL)
1916     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
1917   hex_digits[0]='0';
1918   hex_digits[1]='1';
1919   hex_digits[2]='2';
1920   hex_digits[3]='3';
1921   hex_digits[4]='4';
1922   hex_digits[5]='5';
1923   hex_digits[6]='6';
1924   hex_digits[7]='7';
1925   hex_digits[8]='8';
1926   hex_digits[9]='9';
1927   hex_digits[10]='a';
1928   hex_digits[11]='b';
1929   hex_digits[12]='c';
1930   hex_digits[13]='d';
1931   hex_digits[14]='e';
1932   hex_digits[15]='f';
1933   p=string_info->datum;
1934   q=(unsigned char *) string;
1935   for (i=0; i < (ssize_t) string_info->length; i++)
1936   {
1937     *q++=hex_digits[(*p >> 4) & 0x0f];
1938     *q++=hex_digits[*p & 0x0f];
1939     p++;
1940   }
1941   *q='\0';
1942   return(string);
1943 }
1944 
1945 /*
1946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1947 %                                                                             %
1948 %                                                                             %
1949 %                                                                             %
1950 %   S t r i n g I n f o T o S t r i n g                                       %
1951 %                                                                             %
1952 %                                                                             %
1953 %                                                                             %
1954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1955 %
1956 %  StringInfoToString() converts a string info string to a C string.
1957 %
1958 %  The format of the StringInfoToString method is:
1959 %
1960 %      char *StringInfoToString(const StringInfo *string_info)
1961 %
1962 %  A description of each parameter follows:
1963 %
1964 %    o string_info: the string.
1965 %
1966 */
StringInfoToString(const StringInfo * string_info)1967 MagickExport char *StringInfoToString(const StringInfo *string_info)
1968 {
1969   char
1970     *string;
1971 
1972   size_t
1973     length;
1974 
1975   string=(char *) NULL;
1976   length=string_info->length;
1977   if (~length >= (MagickPathExtent-1))
1978     string=(char *) AcquireQuantumMemory(length+MagickPathExtent,
1979       sizeof(*string));
1980   if (string == (char *) NULL)
1981     return((char *) NULL);
1982   (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
1983   string[length]='\0';
1984   return(string);
1985 }
1986 
1987 /*
1988 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1989 %                                                                             %
1990 %                                                                             %
1991 %                                                                             %
1992 %  S t r i n g T o A r g v                                                    %
1993 %                                                                             %
1994 %                                                                             %
1995 %                                                                             %
1996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1997 %
1998 %  StringToArgv() converts a text string into command line arguments.
1999 %  The 'argv' array of arguments, is returned while the number of arguments
2000 %  is returned via the provided integer variable pointer.
2001 %
2002 %  Simple 'word' tokenizer, which allows for each word to be optionally
2003 %  quoted.  However it will not allow use of partial quotes, or escape
2004 %  characters.
2005 %
2006 %  The format of the StringToArgv method is:
2007 %
2008 %      char **StringToArgv(const char *text,int *argc)
2009 %
2010 %  A description of each parameter follows:
2011 %
2012 %    o argv:  Method StringToArgv returns the string list unless an error
2013 %      occurs, otherwise NULL.
2014 %
2015 %    o text:  Specifies the string to segment into a list.
2016 %
2017 %    o argc:  This integer pointer returns the number of arguments in the
2018 %      list.
2019 %
2020 */
StringToArgv(const char * text,int * argc)2021 MagickExport char **StringToArgv(const char *text,int *argc)
2022 {
2023   char
2024     **argv;
2025 
2026   const char
2027     *p,
2028     *q;
2029 
2030   ssize_t
2031     i;
2032 
2033   *argc=0;
2034   if (text == (char *) NULL)
2035     return((char **) NULL);
2036   /*
2037     Determine the number of arguments.
2038   */
2039   for (p=text; *p != '\0'; )
2040   {
2041     while (isspace((int) ((unsigned char) *p)) != 0)
2042       p++;
2043     if (*p == '\0')
2044       break;
2045     (*argc)++;
2046     if (*p == '"')
2047       for (p++; (*p != '"') && (*p != '\0'); p++) ;
2048     if (*p == '\'')
2049       for (p++; (*p != '\'') && (*p != '\0'); p++) ;
2050     while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2051       p++;
2052   }
2053   (*argc)++;
2054   argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
2055   if (argv == (char **) NULL)
2056     ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2057   /*
2058     Convert string to an ASCII list.
2059   */
2060   argv[0]=AcquireString("magick");
2061   p=text;
2062   for (i=1; i < (ssize_t) *argc; i++)
2063   {
2064     while (isspace((int) ((unsigned char) *p)) != 0)
2065       p++;
2066     q=p;
2067     if (*q == '"')
2068       {
2069         p++;
2070         for (q++; (*q != '"') && (*q != '\0'); q++) ;
2071       }
2072     else
2073       if (*q == '\'')
2074         {
2075           p++;
2076           for (q++; (*q != '\'') && (*q != '\0'); q++) ;
2077         }
2078       else
2079         while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2080           q++;
2081     argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MagickPathExtent,
2082       sizeof(**argv));
2083     if (argv[i] == (char *) NULL)
2084       {
2085         for (i--; i >= 0; i--)
2086           argv[i]=DestroyString(argv[i]);
2087         argv=(char **) RelinquishMagickMemory(argv);
2088         ThrowFatalException(ResourceLimitFatalError,
2089           "UnableToConvertStringToARGV");
2090       }
2091     (void) memcpy(argv[i],p,(size_t) (q-p));
2092     argv[i][q-p]='\0';
2093     p=q;
2094     while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2095       p++;
2096   }
2097   argv[i]=(char *) NULL;
2098   return(argv);
2099 }
2100 
2101 /*
2102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2103 %                                                                             %
2104 %                                                                             %
2105 %                                                                             %
2106 %   S t r i n g T o A r r a y O f D o u b l e s                               %
2107 %                                                                             %
2108 %                                                                             %
2109 %                                                                             %
2110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2111 %
2112 %  StringToArrayOfDoubles() converts a string of space or comma separated
2113 %  numbers into array of floating point numbers (doubles). Any number that
2114 %  failes to parse properly will produce a syntax error. As will two commas
2115 %  without a  number between them.  However a final comma at the end will
2116 %  not be regarded as an error so as to simplify automatic list generation.
2117 %
2118 %  A NULL value is returned on syntax or memory errors.
2119 %
2120 %  Use RelinquishMagickMemory() to free returned array when finished.
2121 %
2122 %  The format of the StringToArrayOfDoubles method is:
2123 %
2124 %     double *StringToArrayOfDoubles(const char *string,size_t *count,
2125 %       ExceptionInfo *exception)
2126 %
2127 %  A description of each parameter follows:
2128 %
2129 %    o string: the string containing the comma/space separated values.
2130 %
2131 %    o count: returns number of arguments in returned array
2132 %
2133 %    o exception: return any errors or warnings in this structure.
2134 %
2135 */
StringToArrayOfDoubles(const char * string,ssize_t * count,ExceptionInfo * exception)2136 MagickExport double *StringToArrayOfDoubles(const char *string,ssize_t *count,
2137   ExceptionInfo *exception)
2138 {
2139   char
2140     *q;
2141 
2142   const char
2143     *p;
2144 
2145   double
2146     *array;
2147 
2148   ssize_t
2149     i;
2150 
2151   /*
2152     Determine count of values, and check syntax.
2153   */
2154   assert(exception != (ExceptionInfo *) NULL);
2155   assert(exception->signature == MagickCoreSignature);
2156   *count=0;
2157   if (string == (char *) NULL)
2158     return((double *) NULL);  /* no value found */
2159   i=0;
2160   p=string;
2161   while (*p != '\0')
2162   {
2163     (void) StringToDouble(p,&q);  /* get value - ignores leading space */
2164     if (p == q)
2165       return((double *) NULL);  /* no value found */
2166     p=q;
2167     i++;  /* increment value count */
2168     while (isspace((int) ((unsigned char) *p)) != 0)
2169       p++;  /* skip spaces */
2170     if (*p == ',')
2171       p++;  /* skip comma */
2172     while (isspace((int) ((unsigned char) *p)) != 0)
2173       p++;  /* and more spaces */
2174   }
2175   /*
2176     Allocate floating point argument list.
2177   */
2178   *count=i;
2179   array=(double *) AcquireQuantumMemory((size_t) i,sizeof(*array));
2180   if (array == (double *) NULL)
2181     {
2182       (void) ThrowMagickException(exception,GetMagickModule(),
2183         ResourceLimitError,"MemoryAllocationFailed","`%s'","");
2184       return((double *) NULL);
2185     }
2186   /*
2187     Fill in the floating point values.
2188   */
2189   i=0;
2190   p=string;
2191   while ((*p != '\0') && (i < *count))
2192   {
2193     array[i++]=StringToDouble(p,&q);
2194     p=q;
2195     while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
2196       p++;
2197   }
2198   return(array);
2199 }
2200 
2201 /*
2202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2203 %                                                                             %
2204 %                                                                             %
2205 %                                                                             %
2206 +   S t r i n g T o k e n                                                     %
2207 %                                                                             %
2208 %                                                                             %
2209 %                                                                             %
2210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2211 %
2212 %  StringToken() looks for any one of given delimiters and splits the string
2213 %  into two separate strings by replacing the delimiter character found with a
2214 %  null character.
2215 %
2216 %  The given string pointer is changed to point to the string following the
2217 %  delimiter character found, or NULL.  A pointer to the start of the
2218 %  string is returned, representing the token before the delimiter.
2219 %
2220 %  StringToken() is similar to the strtok() C library method, but with
2221 %  multiple delimiter characters rather than a delimiter string.
2222 %
2223 %  The format of the StringToken method is:
2224 %
2225 %      char *StringToken(const char *delimiters,char **string)
2226 %
2227 %  A description of each parameter follows:
2228 %
2229 %    o delimiters: one or more delimiters.
2230 %
2231 %    o string: return the first token in the string.  If none is found, return
2232 %      NULL.
2233 %
2234 */
StringToken(const char * delimiters,char ** string)2235 MagickExport char *StringToken(const char *delimiters,char **string)
2236 {
2237   char
2238     *q;
2239 
2240   char
2241     *p;
2242 
2243   const char
2244     *r;
2245 
2246   int
2247     c,
2248     d;
2249 
2250   p=(*string);
2251   if (p == (char *) NULL)
2252     return((char *) NULL);
2253   q=p;
2254   for ( ; ; )
2255   {
2256     c=(*p++);
2257     r=delimiters;
2258     do
2259     {
2260       d=(*r++);
2261       if (c == d)
2262         {
2263           if (c == '\0')
2264             p=(char *) NULL;
2265           else
2266             p[-1]='\0';
2267           *string=p;
2268           return(q);
2269         }
2270     } while (d != '\0');
2271   }
2272 }
2273 
2274 /*
2275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2276 %                                                                             %
2277 %                                                                             %
2278 %                                                                             %
2279 %  S t r i n g T o L i s t                                                    %
2280 %                                                                             %
2281 %                                                                             %
2282 %                                                                             %
2283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2284 %
2285 %  StringToList() converts a text string into a list by segmenting the text
2286 %  string at each carriage return discovered.  The list is converted to HEX
2287 %  characters if any control characters are discovered within the text string.
2288 %
2289 %  The format of the StringToList method is:
2290 %
2291 %      char **StringToList(const char *text)
2292 %
2293 %  A description of each parameter follows:
2294 %
2295 %    o text:  Specifies the string to segment into a list.
2296 %
2297 */
StringToList(const char * text)2298 MagickExport char **StringToList(const char *text)
2299 {
2300   return(StringToStrings(text,(size_t *) NULL));
2301 }
2302 
2303 /*
2304 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2305 %                                                                             %
2306 %                                                                             %
2307 %                                                                             %
2308 %  S t r i n g T o S t r i n g s                                              %
2309 %                                                                             %
2310 %                                                                             %
2311 %                                                                             %
2312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2313 %
2314 %  StringToStrings() converts a text string into a list by segmenting the text
2315 %  string at each carriage return discovered.  The list is converted to HEX
2316 %  characters if any control characters are discovered within the text string.
2317 %
2318 %  The format of the StringToList method is:
2319 %
2320 %      char **StringToList(const char *text,size_t *lines)
2321 %
2322 %  A description of each parameter follows:
2323 %
2324 %    o text:  Specifies the string to segment into a list.
2325 %
2326 %    o count: Return value for the number of items in the list.
2327 %
2328 */
StringToStrings(const char * text,size_t * count)2329 MagickExport char **StringToStrings(const char *text,size_t *count)
2330 {
2331   char
2332     **textlist;
2333 
2334   const char
2335     *p;
2336 
2337   ssize_t
2338     i;
2339 
2340   size_t
2341     lines;
2342 
2343   if (text == (char *) NULL)
2344     {
2345       if (count != (size_t *) NULL)
2346         *count=0;
2347       return((char **) NULL);
2348     }
2349   for (p=text; *p != '\0'; p++)
2350     if (((int) ((unsigned char) *p) < 32) &&
2351         (isspace((int) ((unsigned char) *p)) == 0))
2352       break;
2353   if (*p == '\0')
2354     {
2355       const char
2356         *q;
2357 
2358       /*
2359         Convert string to an ASCII list.
2360       */
2361       lines=1;
2362       for (p=text; *p != '\0'; p++)
2363         if (*p == '\n')
2364           lines++;
2365       textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2366         sizeof(*textlist));
2367       if (textlist == (char **) NULL)
2368         ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2369       p=text;
2370       for (i=0; i < (ssize_t) lines; i++)
2371       {
2372         for (q=p; *q != '\0'; q++)
2373           if ((*q == '\r') || (*q == '\n'))
2374             break;
2375         textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+1,
2376           sizeof(**textlist));
2377         if (textlist[i] == (char *) NULL)
2378           ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2379         (void) memcpy(textlist[i],p,(size_t) (q-p));
2380         textlist[i][q-p]='\0';
2381         if (*q == '\r')
2382           q++;
2383         p=q+1;
2384       }
2385     }
2386   else
2387     {
2388       char
2389         hex_string[MagickPathExtent];
2390 
2391       char
2392         *q;
2393 
2394       ssize_t
2395         j;
2396 
2397       /*
2398         Convert string to a HEX list.
2399       */
2400       lines=(size_t) (strlen(text)/CharsPerLine)+1;
2401       textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2402         sizeof(*textlist));
2403       if (textlist == (char **) NULL)
2404         ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2405       p=text;
2406       for (i=0; i < (ssize_t) lines; i++)
2407       {
2408         size_t
2409           length;
2410 
2411         textlist[i]=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
2412           sizeof(**textlist));
2413         if (textlist[i] == (char *) NULL)
2414           ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2415         (void) FormatLocaleString(textlist[i],MagickPathExtent,"0x%08lx: ",
2416           (long) (CharsPerLine*i));
2417         q=textlist[i]+strlen(textlist[i]);
2418         length=strlen(p);
2419         for (j=1; j <= (ssize_t) MagickMin(length,CharsPerLine); j++)
2420         {
2421           (void) FormatLocaleString(hex_string,MagickPathExtent,"%02x",*(p+j));
2422           (void) CopyMagickString(q,hex_string,MagickPathExtent);
2423           q+=2;
2424           if ((j % 0x04) == 0)
2425             *q++=' ';
2426         }
2427         for ( ; j <= CharsPerLine; j++)
2428         {
2429           *q++=' ';
2430           *q++=' ';
2431           if ((j % 0x04) == 0)
2432             *q++=' ';
2433         }
2434         *q++=' ';
2435         for (j=1; j <= (ssize_t) MagickMin(length,CharsPerLine); j++)
2436         {
2437           if (isprint((int) ((unsigned char) *p)) != 0)
2438             *q++=(*p);
2439           else
2440             *q++='-';
2441           p++;
2442         }
2443         *q='\0';
2444         textlist[i]=(char *) ResizeQuantumMemory(textlist[i],(size_t) (q-
2445           textlist[i]+1),sizeof(**textlist));
2446         if (textlist[i] == (char *) NULL)
2447           ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2448       }
2449     }
2450   if (count != (size_t *) NULL)
2451     *count=lines;
2452   textlist[i]=(char *) NULL;
2453   return(textlist);
2454 }
2455 
2456 /*
2457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2458 %                                                                             %
2459 %                                                                             %
2460 %                                                                             %
2461 %   S t r i n g T o S t r i n g I n f o                                       %
2462 %                                                                             %
2463 %                                                                             %
2464 %                                                                             %
2465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2466 %
2467 %  StringToStringInfo() converts a string to a StringInfo type.
2468 %
2469 %  The format of the StringToStringInfo method is:
2470 %
2471 %      StringInfo *StringToStringInfo(const char *string)
2472 %
2473 %  A description of each parameter follows:
2474 %
2475 %    o string:  The string.
2476 %
2477 */
StringToStringInfo(const char * string)2478 MagickExport StringInfo *StringToStringInfo(const char *string)
2479 {
2480   StringInfo
2481     *string_info;
2482 
2483   assert(string != (const char *) NULL);
2484   string_info=AcquireStringInfo(strlen(string));
2485   SetStringInfoDatum(string_info,(const unsigned char *) string);
2486   return(string_info);
2487 }
2488 
2489 /*
2490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2491 %                                                                             %
2492 %                                                                             %
2493 %                                                                             %
2494 %   S t r i p M a g i c k S t r i n g                                         %
2495 %                                                                             %
2496 %                                                                             %
2497 %                                                                             %
2498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2499 %
2500 %  StripMagickString() strips any whitespace or quotes from the beginning and
2501 %  end of a string of characters. It returns the stripped string length.
2502 %
2503 %  The format of the StripMagickString method is:
2504 %
2505 %      size_t StripMagickString(char *message)
2506 %
2507 %  A description of each parameter follows:
2508 %
2509 %    o message: Specifies an array of characters.
2510 %
2511 */
2512 
StripString(char * message)2513 MagickExport void StripString(char *message)
2514 {
2515   (void) StripMagickString(message);
2516 }
2517 
StripMagickString(char * message)2518 MagickExport size_t StripMagickString(char *message)
2519 {
2520   char
2521     *p,
2522     *q;
2523 
2524   size_t
2525     length;
2526 
2527   assert(message != (char *) NULL);
2528   if (*message == '\0')
2529     return(0);
2530   length=strlen(message);
2531   if (length == 1)
2532     return(1);
2533   p=message;
2534   while (isspace((int) ((unsigned char) *p)) != 0)
2535     p++;
2536   if ((*p == '\'') || (*p == '"'))
2537     p++;
2538   q=message+length-1;
2539   while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2540     q--;
2541   if (q > p)
2542     if ((*q == '\'') || (*q == '"'))
2543       q--;
2544   (void) memmove(message,p,(size_t) (q-p+1));
2545   message[q-p+1]='\0';
2546   for (p=message; *p != '\0'; p++)
2547     if (*p == '\n')
2548       *p=' ';
2549   return((size_t) (q-p+1));
2550 }
2551 
2552 /*
2553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2554 %                                                                             %
2555 %                                                                             %
2556 %                                                                             %
2557 %   S u b s t i t u t e S t r i n g                                           %
2558 %                                                                             %
2559 %                                                                             %
2560 %                                                                             %
2561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2562 %
2563 %  SubstituteString() performs string substitution on a string, replacing the
2564 %  string with the substituted version. Buffer must be allocated from the heap.
2565 %  If the string is matched and status, MagickTrue is returned otherwise
2566 %  MagickFalse.
2567 %
2568 %  The format of the SubstituteString method is:
2569 %
2570 %      MagickBooleanType SubstituteString(char **string,const char *search,
2571 %        const char *replace)
2572 %
2573 %  A description of each parameter follows:
2574 %
2575 %    o string: the string to perform replacements on;  replaced with new
2576 %      allocation if a replacement is made.
2577 %
2578 %    o search: search for this string.
2579 %
2580 %    o replace: replace any matches with this string.
2581 %
2582 */
SubstituteString(char ** string,const char * search,const char * replace)2583 MagickExport MagickBooleanType SubstituteString(char **string,
2584   const char *search,const char *replace)
2585 {
2586   MagickBooleanType
2587     status;
2588 
2589   char
2590     *p;
2591 
2592   size_t
2593     extent,
2594     replace_extent,
2595     search_extent;
2596 
2597   ssize_t
2598     offset;
2599 
2600   status=MagickFalse;
2601   search_extent=0,
2602   replace_extent=0;
2603   for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
2604   {
2605     if (search_extent == 0)
2606       search_extent=strlen(search);
2607     if (strncmp(p,search,search_extent) != 0)
2608       continue;
2609     /*
2610       We found a match.
2611     */
2612     status=MagickTrue;
2613     if (replace_extent == 0)
2614       replace_extent=strlen(replace);
2615     if (replace_extent > search_extent)
2616       {
2617         /*
2618           Make room for the replacement string.
2619         */
2620         offset=(ssize_t) (p-(*string));
2621         extent=strlen(*string)+replace_extent-search_extent+1;
2622         *string=(char *) ResizeQuantumMemory(*string,
2623           OverAllocateMemory(extent+MagickPathExtent),sizeof(*p));
2624         if (*string == (char *) NULL)
2625           ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2626         p=(*string)+offset;
2627       }
2628     /*
2629       Replace string.
2630     */
2631     if (search_extent != replace_extent)
2632       (void) memmove(p+replace_extent,p+search_extent,
2633         strlen(p+search_extent)+1);
2634     (void) memcpy(p,replace,replace_extent);
2635     p+=replace_extent-1;
2636   }
2637   return(status);
2638 }
2639