Coverage Report

Created: 2026-03-31 06:56

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