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