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