MagickCore 7.1.2-35
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{
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{
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{
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{
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
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{
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 i t i z e S t r i n g F o r I d e n t i f i e r %
1587% %
1588% %
1589% %
1590%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1591%
1592% SanitizeStringForIdentifier() returns a new string suitable for use as a C
1593% identifier. Invalid characters are replaced with underscores. An empty
1594% source string becomes a single underscore.
1595%
1596% Free the sanitized string with DestroyString().
1597%
1598% The format of the SanitizeStringForIdentifier method is:
1599%
1600% char *SanitizeStringForIdentifier(const char *source)
1601%
1602% A description of each parameter follows:
1603%
1604% o source: A character string.
1605%
1606*/
1607MagickExport char *SanitizeStringForIdentifier(const char *source)
1608{
1609 char
1610 *p,
1611 *sanitize_source;
1612
1613 static const char
1614 letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_",
1615 digits[] = "0123456789";
1616
1617 assert(source != (const char *) NULL);
1618 sanitize_source=AcquireString(*source == '\0' ? "_" : source);
1619 if (strchr(letters,(int) ((unsigned char) *sanitize_source)) == (char *) NULL)
1620 *sanitize_source='_';
1621 for (p=sanitize_source+1; *p != '\0'; p++)
1622 if ((strchr(letters,(int) ((unsigned char) *p)) == (char *) NULL) &&
1623 (strchr(digits,(int) ((unsigned char) *p)) == (char *) NULL))
1624 *p='_';
1625 return(sanitize_source);
1626}
1627␌
1628/*
1629%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1630% %
1631% %
1632% %
1633% S a n t i z e S t r i n g %
1634% %
1635% %
1636% %
1637%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1638%
1639% SanitizeString() returns a new string with all characters removed except
1640% letters, digits and !#$%&'*+-=?^_`{|}~@.[].
1641%
1642% Free the sanitized string with DestroyString().
1643%
1644% The format of the SanitizeString method is:
1645%
1646% char *SanitizeString(const char *source)
1647%
1648% A description of each parameter follows:
1649%
1650% o source: A character string.
1651%
1652*/
1653MagickExport char *SanitizeString(const char *source)
1654{
1655 char
1656 *sanitize_source;
1657
1658 const char
1659 *q;
1660
1661 char
1662 *p;
1663
1664 static char
1665 allowlist[] =
1666 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 "
1667 "$-_.+!*'(),{}|\\^~[]`\"><#%;/?:@&=";
1668
1669 sanitize_source=AcquireString(source);
1670 p=sanitize_source;
1671 q=sanitize_source+strlen(sanitize_source);
1672 for (p+=strspn(p,allowlist); p != q; p+=(ptrdiff_t) strspn(p,allowlist))
1673 *p='_';
1674 return(sanitize_source);
1675}
1676␌
1677/*
1678%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1679% %
1680% %
1681% %
1682% S e t S t r i n g I n f o %
1683% %
1684% %
1685% %
1686%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1687%
1688% SetStringInfo() copies the source string to the destination string.
1689%
1690% The format of the SetStringInfo method is:
1691%
1692% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1693%
1694% A description of each parameter follows:
1695%
1696% o string_info: the string info.
1697%
1698% o source: the source string.
1699%
1700*/
1701MagickExport void SetStringInfo(StringInfo *string_info,
1702 const StringInfo *source)
1703{
1704 assert(string_info != (StringInfo *) NULL);
1705 assert(string_info->signature == MagickCoreSignature);
1706 assert(source != (StringInfo *) NULL);
1707 assert(source->signature == MagickCoreSignature);
1708 if (string_info->length == 0)
1709 return;
1710 (void) memset(string_info->datum,0,string_info->length);
1711 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1712 source->length));
1713}
1714␌
1715/*
1716%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1717% %
1718% %
1719% %
1720% S e t S t r i n g I n f o D a t u m %
1721% %
1722% %
1723% %
1724%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1725%
1726% SetStringInfoDatum() copies bytes from the source string for the length of
1727% the destination string.
1728%
1729% The format of the SetStringInfoDatum method is:
1730%
1731% void SetStringInfoDatum(StringInfo *string_info,
1732% const unsigned char *source)
1733%
1734% A description of each parameter follows:
1735%
1736% o string_info: the string info.
1737%
1738% o source: the source string.
1739%
1740*/
1741MagickExport void SetStringInfoDatum(StringInfo *string_info,
1742 const unsigned char *source)
1743{
1744 assert(string_info != (StringInfo *) NULL);
1745 assert(string_info->signature == MagickCoreSignature);
1746 if (string_info->length != 0)
1747 (void) memcpy(string_info->datum,source,string_info->length);
1748}
1749␌
1750/*
1751%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1752% %
1753% %
1754% %
1755% S e t S t r i n g I n f o L e n g t h %
1756% %
1757% %
1758% %
1759%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1760%
1761% SetStringInfoLength() set the string length to the specified value.
1762%
1763% The format of the SetStringInfoLength method is:
1764%
1765% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1766%
1767% A description of each parameter follows:
1768%
1769% o string_info: the string info.
1770%
1771% o length: the string length.
1772%
1773*/
1774MagickExport void SetStringInfoLength(StringInfo *string_info,
1775 const size_t length)
1776{
1777 assert(string_info != (StringInfo *) NULL);
1778 assert(string_info->signature == MagickCoreSignature);
1779 if (string_info->length == length)
1780 return;
1781 if (~length < MagickPathExtent)
1782 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1783 string_info->length=length;
1784 if (string_info->datum == (unsigned char *) NULL)
1785 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1786 MagickPathExtent,sizeof(*string_info->datum));
1787 else
1788 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1789 length+MagickPathExtent,sizeof(*string_info->datum));
1790 if (string_info->datum == (unsigned char *) NULL)
1791 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1792}
1793␌
1794/*
1795%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1796% %
1797% %
1798% %
1799% S e t S t r i n g I n f o N a m e %
1800% %
1801% %
1802% %
1803%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1804%
1805% SetStringInfoName() sets the name associated with the string.
1806%
1807% The format of the SetStringInfoName method is:
1808%
1809% void SetStringInfoName(StringInfo *string_info,const char *name)
1810%
1811% A description of each parameter follows:
1812%
1813% o string_info: the string info.
1814%
1815% o name: the name.
1816%
1817*/
1818MagickExport void SetStringInfoName(StringInfo *string_info,const char *name)
1819{
1820 assert(string_info != (StringInfo *) NULL);
1821 assert(string_info->signature == MagickCoreSignature);
1822 assert(name != (const char *) NULL);
1823 string_info->name=ConstantString(name);
1824}
1825␌
1826/*
1827%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1828% %
1829% %
1830% %
1831% S e t S t r i n g I n f o P a t h %
1832% %
1833% %
1834% %
1835%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1836%
1837% SetStringInfoPath() sets the path associated with the string.
1838%
1839% The format of the SetStringInfoPath method is:
1840%
1841% void SetStringInfoPath(StringInfo *string_info,const char *path)
1842%
1843% A description of each parameter follows:
1844%
1845% o string_info: the string info.
1846%
1847% o path: the path.
1848%
1849*/
1850MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1851{
1852 assert(string_info != (StringInfo *) NULL);
1853 assert(string_info->signature == MagickCoreSignature);
1854 assert(path != (const char *) NULL);
1855 string_info->path=ConstantString(path);
1856}
1857␌
1858/*
1859%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1860% %
1861% %
1862% %
1863% S p l i t S t r i n g I n f o %
1864% %
1865% %
1866% %
1867%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1868%
1869% SplitStringInfo() splits a string into two and returns it.
1870%
1871% The format of the SplitStringInfo method is:
1872%
1873% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1874%
1875% A description of each parameter follows:
1876%
1877% o string_info: the string info.
1878%
1879*/
1880MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1881 const size_t offset)
1882{
1884 *split_info;
1885
1886 assert(string_info != (StringInfo *) NULL);
1887 assert(string_info->signature == MagickCoreSignature);
1888 if (offset > string_info->length)
1889 return((StringInfo *) NULL);
1890 split_info=AcquireStringInfo(offset);
1891 SetStringInfo(split_info,string_info);
1892 (void) memmove(string_info->datum,string_info->datum+offset,
1893 string_info->length-offset+MagickPathExtent);
1894 SetStringInfoLength(string_info,string_info->length-offset);
1895 return(split_info);
1896}
1897␌
1898/*
1899%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1900% %
1901% %
1902% %
1903% S t r i n g I n f o T o D i g e s t %
1904% %
1905% %
1906% %
1907%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1908%
1909% StringInfoToDigest() converts a string info string to a hex digest.
1910%
1911% The format of the StringInfoToString method is:
1912%
1913% char *StringInfoToDigest(const StringInfo *signature)
1914%
1915% A description of each parameter follows:
1916%
1917% o string_info: the string.
1918%
1919*/
1920MagickExport char *StringInfoToDigest(const StringInfo *signature)
1921{
1922 char
1923 *digest;
1924
1926 *signature_info;
1927
1928 signature_info=AcquireSignatureInfo();
1929 UpdateSignature(signature_info,signature);
1930 FinalizeSignature(signature_info);
1931 digest=StringInfoToHexString(GetSignatureDigest(signature_info));
1932 signature_info=DestroySignatureInfo(signature_info);
1933 return(digest);
1934}
1935␌
1936/*
1937%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1938% %
1939% %
1940% %
1941% S t r i n g I n f o T o H e x S t r i n g %
1942% %
1943% %
1944% %
1945%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1946%
1947% StringInfoToHexString() converts a string info string to a C string.
1948%
1949% The format of the StringInfoToHexString method is:
1950%
1951% char *StringInfoToHexString(const StringInfo *string_info)
1952%
1953% A description of each parameter follows:
1954%
1955% o string_info: the string.
1956%
1957*/
1958MagickExport char *StringInfoToHexString(const StringInfo *string_info)
1959{
1960 char
1961 *string;
1962
1963 const unsigned char
1964 *p;
1965
1966 ssize_t
1967 i;
1968
1969 unsigned char
1970 *q;
1971
1972 size_t
1973 length;
1974
1975 unsigned char
1976 hex_digits[16];
1977
1978 length=string_info->length;
1979 if (~length < MagickPathExtent)
1980 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
1981 string=(char *) AcquireQuantumMemory(length+MagickPathExtent,2*
1982 sizeof(*string));
1983 if (string == (char *) NULL)
1984 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
1985 hex_digits[0]='0';
1986 hex_digits[1]='1';
1987 hex_digits[2]='2';
1988 hex_digits[3]='3';
1989 hex_digits[4]='4';
1990 hex_digits[5]='5';
1991 hex_digits[6]='6';
1992 hex_digits[7]='7';
1993 hex_digits[8]='8';
1994 hex_digits[9]='9';
1995 hex_digits[10]='a';
1996 hex_digits[11]='b';
1997 hex_digits[12]='c';
1998 hex_digits[13]='d';
1999 hex_digits[14]='e';
2000 hex_digits[15]='f';
2001 p=string_info->datum;
2002 q=(unsigned char *) string;
2003 for (i=0; i < (ssize_t) string_info->length; i++)
2004 {
2005 *q++=hex_digits[(*p >> 4) & 0x0f];
2006 *q++=hex_digits[*p & 0x0f];
2007 p++;
2008 }
2009 *q='\0';
2010 return(string);
2011}
2012␌
2013/*
2014%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2015% %
2016% %
2017% %
2018% S t r i n g I n f o T o S t r i n g %
2019% %
2020% %
2021% %
2022%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2023%
2024% StringInfoToString() converts a string info string to a C string.
2025%
2026% The format of the StringInfoToString method is:
2027%
2028% char *StringInfoToString(const StringInfo *string_info)
2029%
2030% A description of each parameter follows:
2031%
2032% o string_info: the string.
2033%
2034*/
2035MagickExport char *StringInfoToString(const StringInfo *string_info)
2036{
2037 char
2038 *string;
2039
2040 size_t
2041 length;
2042
2043 string=(char *) NULL;
2044 length=string_info->length;
2045 if (~length >= (MagickPathExtent-1))
2046 string=(char *) AcquireQuantumMemory(length+MagickPathExtent,
2047 sizeof(*string));
2048 if (string == (char *) NULL)
2049 return((char *) NULL);
2050 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
2051 string[length]='\0';
2052 return(string);
2053}
2054␌
2055/*
2056%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2057% %
2058% %
2059% %
2060% S t r i n g T o A r g v %
2061% %
2062% %
2063% %
2064%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2065%
2066% StringToArgv() converts a text string into command line arguments.
2067% The 'argv' array of arguments, is returned while the number of arguments
2068% is returned via the provided integer variable pointer.
2069%
2070% Simple 'word' tokenizer, which allows for each word to be optionally
2071% quoted. However it will not allow use of partial quotes, or escape
2072% characters.
2073%
2074% The format of the StringToArgv method is:
2075%
2076% char **StringToArgv(const char *text,int *argc)
2077%
2078% A description of each parameter follows:
2079%
2080% o argv: Method StringToArgv returns the string list unless an error
2081% occurs, otherwise NULL.
2082%
2083% o text: Specifies the string to segment into a list.
2084%
2085% o argc: This integer pointer returns the number of arguments in the
2086% list.
2087%
2088*/
2089MagickExport char **StringToArgv(const char *text,int *argc)
2090{
2091 char
2092 **argv;
2093
2094 const char
2095 *p = text;
2096
2097 ssize_t
2098 i;
2099
2100 /*
2101 Determine the number of arguments.
2102 */
2103 *argc=0;
2104 if (text == (const char *) NULL)
2105 return((char **) NULL);
2106 while (*p != '\0')
2107 {
2108 /*
2109 Skip whitespace and backtick delimiters.
2110 */
2111 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == '`'))
2112 p++;
2113 if (*p == '\0')
2114 break;
2115 (*argc)++;
2116 /*
2117 Shell operators are returned as individual arguments.
2118 */
2119 if ((*p == '&') && (*(p+1) == '&'))
2120 {
2121 p+=2;
2122 continue;
2123 }
2124 if ((*p == '|') && (*(p+1) == '|'))
2125 {
2126 p+=2;
2127 continue;
2128 }
2129 if ((*p == ';') || (*p == '&') || (*p == '|'))
2130 {
2131 p++;
2132 continue;
2133 }
2134 /*
2135 Consume one argument.
2136 */
2137 while ((*p != '\0') &&
2138 (isspace((int) ((unsigned char) *p)) == 0) &&
2139 (*p != '`') && (*p != ';') && (*p != '&') && (*p != '|'))
2140 {
2141 if (*p == '\\')
2142 {
2143 p++; /* Skip the escape character */
2144 if (*p != '\0')
2145 p++; /* Skip the escaped character */
2146 continue;
2147 }
2148 if ((*p == '"') || (*p == '\''))
2149 {
2150 const char quote = (*p++);
2151 while ((*p != quote) && (*p != '\0'))
2152 {
2153 if ((quote == '"') && (*p == '\\'))
2154 {
2155 p++;
2156 if (*p != '\0')
2157 p++;
2158 continue;
2159 }
2160 p++;
2161 }
2162 if (*p == quote)
2163 p++;
2164 continue;
2165 }
2166 p++;
2167 }
2168 }
2169 /*
2170 Instantiate argv.
2171 */
2172 (*argc)++;
2173 argv=(char **) AcquireQuantumMemory((size_t) *argc+1UL,sizeof(*argv));
2174 if (argv == (char **) NULL)
2175 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2176 /*
2177 Convert the string to an ASCII argument list.
2178 */
2179 argv[0]=AcquireString(GetClientName());
2180 p=text;
2181 for (i=1; i < (ssize_t) *argc; i++)
2182 {
2183 const char
2184 *q;
2185
2186 size_t
2187 length = 0;
2188
2189 /*
2190 Skip whitespace and backtick delimiters.
2191 */
2192 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == '`'))
2193 p++;
2194 q=p;
2195 if ((*q == '&') && (*(q+1) == '&'))
2196 q+=2;
2197 else
2198 if ((*q == '|') && (*(q+1) == '|'))
2199 q+=2;
2200 else
2201 if ((*q == ';') || (*q == '&') || (*q == '|'))
2202 q++;
2203 else
2204 {
2205 while ((*q != '\0') &&
2206 (isspace((int) ((unsigned char) *q)) == 0) &&
2207 (*q != '`') && (*q != ';') && (*q != '&') && (*q != '|'))
2208 {
2209 if (*q == '\\')
2210 {
2211 q++;
2212 if (*q != '\0')
2213 q++;
2214 continue;
2215 }
2216 if ((*q == '"') || (*q == '\''))
2217 {
2218 const char quote = (*q++);
2219 while ((*q != quote) && (*q != '\0'))
2220 {
2221 if ((quote == '"') && (*q == '\\'))
2222 {
2223 q++;
2224 if (*q != '\0')
2225 q++;
2226 continue;
2227 }
2228 q++;
2229 }
2230 if (*q == quote)
2231 q++;
2232 continue;
2233 }
2234 q++;
2235 }
2236 }
2237 /*
2238 Allocate buffer matching at least the raw substring size + safety padding.
2239 */
2240 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MagickPathExtent,
2241 sizeof(**argv));
2242 if (argv[i] == (char *) NULL)
2243 {
2244 for (i--; i >= 0; i--)
2245 argv[i]=DestroyString(argv[i]);
2246 argv=(char **) RelinquishMagickMemory(argv);
2247 ThrowFatalException(ResourceLimitFatalError,
2248 "UnableToConvertStringToARGV");
2249 }
2250 /*
2251 Copy data while unescaping and stripping quotes incrementally.
2252 */
2253 if (((p != q) && ((*p == ';') || (*p == '&') || (*p == '|'))))
2254 {
2255 while (p < q)
2256 argv[i][length++]=(*p++);
2257 }
2258 else
2259 {
2260 while (p < q)
2261 {
2262 if (*p == '\\')
2263 {
2264 p++; /* Skip '\\' */
2265 if (p < q)
2266 argv[i][length++]=(*p++);
2267 continue;
2268 }
2269 if ((*p == '"') || (*p == '\''))
2270 {
2271 const char quote = *p++; /* Skip open quote */
2272 while ((p < q) && (*p != quote))
2273 {
2274 if ((quote == '"') && (*p == '\\'))
2275 {
2276 p++; /* Skip inner '\\' */
2277 if (p < q)
2278 argv[i][length++]=(*p++);
2279 continue;
2280 }
2281 argv[i][length++]=(*p++);
2282 }
2283 if ((p < q) && (*p == quote))
2284 p++; /* Skip close quote */
2285 continue;
2286 }
2287 argv[i][length++]=(*p++);
2288 }
2289 }
2290 argv[i][length]='\0';
2291 }
2292 argv[i]=(char *) NULL;
2293 return(argv);
2294}
2295␌
2296/*
2297%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2298% %
2299% %
2300% %
2301% S t r i n g T o A r r a y O f D o u b l e s %
2302% %
2303% %
2304% %
2305%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2306%
2307% StringToArrayOfDoubles() converts a string of space or comma separated
2308% numbers into array of floating point numbers (doubles). Any number that
2309% fails to parse properly will produce a syntax error. As will two commas
2310% without a number between them. However a final comma at the end will
2311% not be regarded as an error so as to simplify automatic list generation.
2312%
2313% A NULL value is returned on syntax or memory errors.
2314%
2315% Use RelinquishMagickMemory() to free returned array when finished.
2316%
2317% The format of the StringToArrayOfDoubles method is:
2318%
2319% double *StringToArrayOfDoubles(const char *string,size_t *count,
2320% ExceptionInfo *exception)
2321%
2322% A description of each parameter follows:
2323%
2324% o string: the string containing the comma/space separated values.
2325%
2326% o count: returns number of arguments in returned array
2327%
2328% o exception: return any errors or warnings in this structure.
2329%
2330*/
2331MagickExport double *StringToArrayOfDoubles(const char *string,ssize_t *count,
2332 ExceptionInfo *exception)
2333{
2334 char
2335 *q;
2336
2337 const char
2338 *p;
2339
2340 double
2341 *array;
2342
2343 ssize_t
2344 i;
2345
2346 /*
2347 Determine count of values, and check syntax.
2348 */
2349 assert(exception != (ExceptionInfo *) NULL);
2350 assert(exception->signature == MagickCoreSignature);
2351 *count=0;
2352 if (string == (char *) NULL)
2353 return((double *) NULL); /* no value found */
2354 i=0;
2355 p=string;
2356 while (*p != '\0')
2357 {
2358 (void) StringToDouble(p,&q); /* get value - ignores leading space */
2359 if (p == q)
2360 return((double *) NULL); /* no value found */
2361 p=q;
2362 i++; /* increment value count */
2363 while (isspace((int) ((unsigned char) *p)) != 0)
2364 p++; /* skip spaces */
2365 if (*p == ',')
2366 p++; /* skip comma */
2367 while (isspace((int) ((unsigned char) *p)) != 0)
2368 p++; /* and more spaces */
2369 }
2370 /*
2371 Allocate floating point argument list.
2372 */
2373 *count=i;
2374 array=(double *) AcquireQuantumMemory((size_t) i,sizeof(*array));
2375 if (array == (double *) NULL)
2376 {
2377 (void) ThrowMagickException(exception,GetMagickModule(),
2378 ResourceLimitError,"MemoryAllocationFailed","`%s'","");
2379 return((double *) NULL);
2380 }
2381 /*
2382 Fill in the floating point values.
2383 */
2384 i=0;
2385 p=string;
2386 while ((*p != '\0') && (i < *count))
2387 {
2388 array[i++]=StringToDouble(p,&q);
2389 p=q;
2390 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
2391 p++;
2392 }
2393 return(array);
2394}
2395␌
2396/*
2397%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2398% %
2399% %
2400% %
2401+ S t r i n g T o k e n %
2402% %
2403% %
2404% %
2405%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2406%
2407% StringToken() looks for any one of given delimiters and splits the string
2408% into two separate strings by replacing the delimiter character found with a
2409% null character.
2410%
2411% The given string pointer is changed to point to the string following the
2412% delimiter character found, or NULL. A pointer to the start of the
2413% string is returned, representing the token before the delimiter.
2414%
2415% StringToken() is similar to the strtok() C library method, but with
2416% multiple delimiter characters rather than a delimiter string.
2417%
2418% The format of the StringToken method is:
2419%
2420% char *StringToken(const char *delimiters,char **string)
2421%
2422% A description of each parameter follows:
2423%
2424% o delimiters: one or more delimiters.
2425%
2426% o string: return the first token in the string. If none is found, return
2427% NULL.
2428%
2429*/
2430MagickExport char *StringToken(const char *delimiters,char **string)
2431{
2432 char
2433 *q;
2434
2435 char
2436 *p;
2437
2438 const char
2439 *r;
2440
2441 int
2442 c,
2443 d;
2444
2445 p=(*string);
2446 if (p == (char *) NULL)
2447 return((char *) NULL);
2448 q=p;
2449 for ( ; ; )
2450 {
2451 c=(*p++);
2452 r=delimiters;
2453 do
2454 {
2455 d=(*r++);
2456 if (c == d)
2457 {
2458 if (c == '\0')
2459 p=(char *) NULL;
2460 else
2461 p[-1]='\0';
2462 *string=p;
2463 return(q);
2464 }
2465 } while (d != '\0');
2466 }
2467}
2468␌
2469/*
2470%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2471% %
2472% %
2473% %
2474% S t r i n g T o L i s t %
2475% %
2476% %
2477% %
2478%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2479%
2480% StringToList() converts a text string into a list by segmenting the text
2481% string at each carriage return discovered. The list is converted to HEX
2482% characters if any control characters are discovered within the text string.
2483%
2484% The format of the StringToList method is:
2485%
2486% char **StringToList(const char *text)
2487%
2488% A description of each parameter follows:
2489%
2490% o text: Specifies the string to segment into a list.
2491%
2492*/
2493MagickExport char **StringToList(const char *text)
2494{
2495 return(StringToStrings(text,(size_t *) NULL));
2496}
2497␌
2498/*
2499%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2500% %
2501% %
2502% %
2503% S t r i n g T o S t r i n g s %
2504% %
2505% %
2506% %
2507%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2508%
2509% StringToStrings() converts a text string into a list by segmenting the text
2510% string at each carriage return discovered. The list is converted to HEX
2511% characters if any control characters are discovered within the text string.
2512%
2513% The format of the StringToList method is:
2514%
2515% char **StringToList(const char *text,size_t *lines)
2516%
2517% A description of each parameter follows:
2518%
2519% o text: Specifies the string to segment into a list.
2520%
2521% o count: Return value for the number of items in the list.
2522%
2523*/
2524MagickExport char **StringToStrings(const char *text,size_t *count)
2525{
2526 char
2527 **textlist;
2528
2529 const char
2530 *p;
2531
2532 ssize_t
2533 i;
2534
2535 size_t
2536 lines;
2537
2538 if (text == (char *) NULL)
2539 {
2540 if (count != (size_t *) NULL)
2541 *count=0;
2542 return((char **) NULL);
2543 }
2544 for (p=text; *p != '\0'; p++)
2545 if (((int) ((unsigned char) *p) < 32) &&
2546 (isspace((int) ((unsigned char) *p)) == 0))
2547 break;
2548 if (*p == '\0')
2549 {
2550 const char
2551 *q;
2552
2553 /*
2554 Convert string to an ASCII list.
2555 */
2556 lines=1;
2557 for (p=text; *p != '\0'; p++)
2558 if (*p == '\n')
2559 lines++;
2560 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2561 sizeof(*textlist));
2562 if (textlist == (char **) NULL)
2563 return((char **) NULL);
2564 p=text;
2565 for (i=0; i < (ssize_t) lines; i++)
2566 {
2567 for (q=p; *q != '\0'; q++)
2568 if ((*q == '\r') || (*q == '\n'))
2569 break;
2570 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+1,
2571 sizeof(**textlist));
2572 if (textlist[i] == (char *) NULL)
2573 {
2574 ssize_t
2575 j;
2576
2577 for (j=0; j < i; j++)
2578 textlist[j]=DestroyString(textlist[j]);
2579 textlist=(char **) RelinquishMagickMemory(textlist);
2580 return((char **) NULL);
2581 }
2582 (void) memcpy(textlist[i],p,(size_t) (q-p));
2583 textlist[i][q-p]='\0';
2584 if (*q == '\r')
2585 q++;
2586 p=q+1;
2587 }
2588 }
2589 else
2590 {
2591 char
2592 hex_string[MagickPathExtent];
2593
2594 char
2595 *q;
2596
2597 ssize_t
2598 j;
2599
2600 /*
2601 Convert string to a HEX list.
2602 */
2603 lines=(size_t) (strlen(text)/CharsPerLine)+1;
2604 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2605 sizeof(*textlist));
2606 if (textlist == (char **) NULL)
2607 return((char **) NULL);
2608 p=text;
2609 for (i=0; i < (ssize_t) lines; i++)
2610 {
2611 size_t
2612 length;
2613
2614 textlist[i]=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
2615 sizeof(**textlist));
2616 if (textlist[i] == (char *) NULL)
2617 {
2618 for (j=0; j < i; j++)
2619 textlist[j]=DestroyString(textlist[j]);
2620 textlist=(char **) RelinquishMagickMemory(textlist);
2621 return((char **) NULL);
2622 }
2623 (void) FormatLocaleString(textlist[i],MagickPathExtent,"0x%08lx: ",
2624 (long) (CharsPerLine*i));
2625 q=textlist[i]+strlen(textlist[i]);
2626 length=strlen(p);
2627 for (j=1; j <= (ssize_t) MagickMin(length,CharsPerLine); j++)
2628 {
2629 (void) FormatLocaleString(hex_string,MagickPathExtent,"%02x",*(p+j));
2630 (void) CopyMagickString(q,hex_string,MagickPathExtent);
2631 q+=(ptrdiff_t) 2;
2632 if ((j % 0x04) == 0)
2633 *q++=' ';
2634 }
2635 for ( ; j <= CharsPerLine; j++)
2636 {
2637 *q++=' ';
2638 *q++=' ';
2639 if ((j % 0x04) == 0)
2640 *q++=' ';
2641 }
2642 *q++=' ';
2643 for (j=1; j <= (ssize_t) MagickMin(length,CharsPerLine); j++)
2644 {
2645 if (isprint((int) ((unsigned char) *p)) != 0)
2646 *q++=(*p);
2647 else
2648 *q++='-';
2649 p++;
2650 }
2651 *q='\0';
2652 {
2653 char
2654 *resized;
2655
2656 resized=(char *) ResizeQuantumMemory(textlist[i],(size_t) (q-
2657 textlist[i]+1),sizeof(**textlist));
2658 if (resized == (char *) NULL)
2659 {
2660 textlist[i]=(char *) NULL;
2661 for (j=0; j < i; j++)
2662 textlist[j]=DestroyString(textlist[j]);
2663 textlist=(char **) RelinquishMagickMemory(textlist);
2664 return((char **) NULL);
2665 }
2666 textlist[i]=resized;
2667 }
2668 }
2669 }
2670 if (count != (size_t *) NULL)
2671 *count=lines;
2672 textlist[i]=(char *) NULL;
2673 return(textlist);
2674}
2675␌
2676/*
2677%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2678% %
2679% %
2680% %
2681% S t r i n g T o S t r i n g I n f o %
2682% %
2683% %
2684% %
2685%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2686%
2687% StringToStringInfo() converts a string to a StringInfo type.
2688%
2689% The format of the StringToStringInfo method is:
2690%
2691% StringInfo *StringToStringInfo(const char *string)
2692%
2693% A description of each parameter follows:
2694%
2695% o string: The string.
2696%
2697*/
2698MagickExport StringInfo *StringToStringInfo(const char *string)
2699{
2701 *string_info;
2702
2703 assert(string != (const char *) NULL);
2704 string_info=AcquireStringInfo(strlen(string));
2705 SetStringInfoDatum(string_info,(const unsigned char *) string);
2706 return(string_info);
2707}
2708␌
2709/*
2710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2711% %
2712% %
2713% %
2714% S t r i p M a g i c k S t r i n g %
2715% %
2716% %
2717% %
2718%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2719%
2720% StripMagickString() strips any whitespace or quotes from the beginning and
2721% end of a string of characters. It returns the stripped string length.
2722%
2723% The format of the StripMagickString method is:
2724%
2725% size_t StripMagickString(char *message)
2726%
2727% A description of each parameter follows:
2728%
2729% o message: Specifies an array of characters.
2730%
2731*/
2732
2733MagickExport void StripString(char *message)
2734{
2735 (void) StripMagickString(message);
2736}
2737
2738MagickExport size_t StripMagickString(char *message)
2739{
2740 char
2741 *p,
2742 *q;
2743
2744 size_t
2745 length;
2746
2747 assert(message != (char *) NULL);
2748 if (*message == '\0')
2749 return(0);
2750 length=strlen(message);
2751 if (length == 1)
2752 return(1);
2753 p=message;
2754 while (isspace((int) ((unsigned char) *p)) != 0)
2755 p++;
2756 if ((*p == '\'') || (*p == '"'))
2757 p++;
2758 q=message+length-1;
2759 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2760 q--;
2761 if (q > p)
2762 if ((*q == '\'') || (*q == '"'))
2763 q--;
2764 (void) memmove(message,p,(size_t) (q-p+1));
2765 message[q-p+1]='\0';
2766 for (p=message; *p != '\0'; p++)
2767 if (*p == '\n')
2768 *p=' ';
2769 return((size_t) (q-p+1));
2770}
2771␌
2772/*
2773%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2774% %
2775% %
2776% %
2777% S u b s t i t u t e S t r i n g %
2778% %
2779% %
2780% %
2781%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2782%
2783% SubstituteString() performs string substitution on a string, replacing the
2784% string with the substituted version. Buffer must be allocated from the heap.
2785% If the string is matched and status, MagickTrue is returned otherwise
2786% MagickFalse.
2787%
2788% The format of the SubstituteString method is:
2789%
2790% MagickBooleanType SubstituteString(char **string,const char *search,
2791% const char *replace)
2792%
2793% A description of each parameter follows:
2794%
2795% o string: the string to perform replacements on; replaced with new
2796% allocation if a replacement is made.
2797%
2798% o search: search for this string.
2799%
2800% o replace: replace any matches with this string.
2801%
2802*/
2803MagickExport MagickBooleanType SubstituteString(char **string,
2804 const char *search,const char *replace)
2805{
2806 MagickBooleanType
2807 status;
2808
2809 char
2810 *p;
2811
2812 size_t
2813 extent,
2814 replace_extent,
2815 search_extent;
2816
2817 ssize_t
2818 offset;
2819
2820 status=MagickFalse;
2821 search_extent=0,
2822 replace_extent=0;
2823 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
2824 {
2825 if (search_extent == 0)
2826 search_extent=strlen(search);
2827 if (strncmp(p,search,search_extent) != 0)
2828 continue;
2829 /*
2830 We found a match.
2831 */
2832 status=MagickTrue;
2833 if (replace_extent == 0)
2834 replace_extent=strlen(replace);
2835 if (replace_extent > search_extent)
2836 {
2837 /*
2838 Make room for the replacement string.
2839 */
2840 offset=(ssize_t) (p-(*string));
2841 extent=strlen(*string)+replace_extent-search_extent+1;
2842 *string=(char *) ResizeQuantumMemory(*string,
2843 OverAllocateMemory(extent+MagickPathExtent),sizeof(*p));
2844 if (*string == (char *) NULL)
2845 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2846 p=(*string)+offset;
2847 }
2848 /*
2849 Replace string.
2850 */
2851 if (search_extent != replace_extent)
2852 (void) memmove(p+replace_extent,p+search_extent,
2853 strlen(p+search_extent)+1);
2854 (void) memcpy(p,replace,replace_extent);
2855 p+=(ptrdiff_t) replace_extent-1;
2856 }
2857 return(status);
2858}