MagickCore  7.0.10
policy.c
Go to the documentation of this file.
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % PPPP OOO L IIIII CCCC Y Y %
6 % P P O O L I C Y Y %
7 % PPPP O O L I C Y %
8 % P O O L I C Y %
9 % P OOO LLLLL IIIII CCCC Y %
10 % %
11 % %
12 % MagickCore Policy Methods %
13 % %
14 % Software Design %
15 % Cristy %
16 % July 1992 %
17 % %
18 % %
19 % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
21 % %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
24 % %
25 % https://imagemagick.org/script/license.php %
26 % %
27 % Unless required by applicable law or agreed to in writing, software %
28 % distributed under the License is distributed on an "AS IS" BASIS, %
29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30 % See the License for the specific language governing permissions and %
31 % limitations under the License. %
32 % %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %
35 % We use linked-lists because splay-trees do not currently support duplicate
36 % key / value pairs (.e.g X11 green compliance and SVG green compliance).
37 %
38 */
39 
40 /*
41  Include declarations.
42 */
43 #include "MagickCore/studio.h"
45 #include "MagickCore/client.h"
46 #include "MagickCore/configure.h"
48 #include "MagickCore/exception.h"
51 #include "MagickCore/memory_.h"
53 #include "MagickCore/monitor.h"
55 #include "MagickCore/option.h"
56 #include "MagickCore/policy.h"
58 #include "MagickCore/resource_.h"
60 #include "MagickCore/semaphore.h"
62 #include "MagickCore/string_.h"
64 #include "MagickCore/token.h"
65 #include "MagickCore/utility.h"
67 #include "MagickCore/xml-tree.h"
69 
70 /*
71  Define declarations.
72 */
73 #define PolicyFilename "policy.xml"
74 
75 /*
76  Typedef declarations.
77 */
79 {
80  char
81  *path;
82 
85 
88 
89  char
90  *name,
91  *pattern,
92  *value;
93 
96  stealth,
97  debug;
98 
101 
102  size_t
104 };
105 
106 typedef struct _PolicyMapInfo
107 {
108  const PolicyDomain
110 
111  const PolicyRights
113 
114  const char
116  *pattern,
117  *value;
118 } PolicyMapInfo;
119 
120 /*
121  Static declarations.
122 */
123 static const PolicyMapInfo
125  {
126  { UndefinedPolicyDomain, UndefinedPolicyRights, (const char *) NULL,
127  (const char *) NULL, (const char *) NULL }
128  };
129 
130 static LinkedListInfo
132 
133 static SemaphoreInfo
135 
136 /*
137  Forward declarations.
138 */
139 static MagickBooleanType
141  LoadPolicyCache(LinkedListInfo *,const char *,const char *,const size_t,
142  ExceptionInfo *);
143 
144 /*
145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 % %
147 % %
148 % %
149 % A c q u i r e P o l i c y C a c h e %
150 % %
151 % %
152 % %
153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154 %
155 % AcquirePolicyCache() caches one or more policy configurations which provides
156 % a mapping between policy attributes and a policy name.
157 %
158 % The format of the AcquirePolicyCache method is:
159 %
160 % LinkedListInfo *AcquirePolicyCache(const char *filename,
161 % ExceptionInfo *exception)
162 %
163 % A description of each parameter follows:
164 %
165 % o filename: the policy configuration file name.
166 %
167 % o exception: return any errors or warnings in this structure.
168 %
169 */
170 static LinkedListInfo *AcquirePolicyCache(const char *filename,
171  ExceptionInfo *exception)
172 {
174  *cache;
175 
177  status;
178 
179  ssize_t
180  i;
181 
182  /*
183  Load external policy map.
184  */
185  cache=NewLinkedList(0);
186  status=MagickTrue;
187 #if MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
188  (void) filename;
189  status=LoadPolicyCache(cache,ZeroConfigurationPolicy,"[zero-configuration]",0,
190  exception);
191 #else
192  {
193  const StringInfo
194  *option;
195 
197  *options;
198 
199  options=GetConfigureOptions(filename,exception);
200  option=(const StringInfo *) GetNextValueInLinkedList(options);
201  while (option != (const StringInfo *) NULL)
202  {
203  status&=LoadPolicyCache(cache,(const char *) GetStringInfoDatum(option),
204  GetStringInfoPath(option),0,exception);
205  option=(const StringInfo *) GetNextValueInLinkedList(options);
206  }
207  options=DestroyConfigureOptions(options);
208  }
209 #endif
210  /*
211  Load built-in policy map.
212  */
213  for (i=0; i < (ssize_t) (sizeof(PolicyMap)/sizeof(*PolicyMap)); i++)
214  {
215  PolicyInfo
216  *policy_info;
217 
218  const PolicyMapInfo
219  *p;
220 
221  p=PolicyMap+i;
222  policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
223  if (policy_info == (PolicyInfo *) NULL)
224  {
225  (void) ThrowMagickException(exception,GetMagickModule(),
226  ResourceLimitError,"MemoryAllocationFailed","`%s'",
227  p->name == (char *) NULL ? "" : p->name);
228  continue;
229  }
230  (void) memset(policy_info,0,sizeof(*policy_info));
231  policy_info->path=(char *) "[built-in]";
232  policy_info->domain=p->domain;
233  policy_info->rights=p->rights;
234  policy_info->name=(char *) p->name;
235  policy_info->pattern=(char *) p->pattern;
236  policy_info->value=(char *) p->value;
237  policy_info->exempt=MagickTrue;
238  policy_info->signature=MagickCoreSignature;
239  status&=AppendValueToLinkedList(cache,policy_info);
240  if (status == MagickFalse)
241  (void) ThrowMagickException(exception,GetMagickModule(),
242  ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name);
243  }
244  return(cache);
245 }
246 
247 /*
248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249 % %
250 % %
251 % %
252 + G e t P o l i c y I n f o %
253 % %
254 % %
255 % %
256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257 %
258 % GetPolicyInfo() searches the policy list for the specified name and if found
259 % returns attributes for that policy.
260 %
261 % The format of the GetPolicyInfo method is:
262 %
263 % PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
264 %
265 % A description of each parameter follows:
266 %
267 % o name: the policy name.
268 %
269 % o exception: return any errors or warnings in this structure.
270 %
271 */
272 static PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
273 {
274  char
275  policyname[MagickPathExtent];
276 
278  domain;
279 
280  PolicyInfo
281  *p;
282 
283  char
284  *q;
285 
286  assert(exception != (ExceptionInfo *) NULL);
287  if (IsPolicyCacheInstantiated(exception) == MagickFalse)
288  return((PolicyInfo *) NULL);
289  /*
290  Strip names of whitespace.
291  */
292  *policyname='\0';
293  if (name != (const char *) NULL)
294  (void) CopyMagickString(policyname,name,MagickPathExtent);
295  for (q=policyname; *q != '\0'; q++)
296  {
297  if (isspace((int) ((unsigned char) *q)) == 0)
298  continue;
299  (void) CopyMagickString(q,q+1,MagickPathExtent);
300  q--;
301  }
302  /*
303  Strip domain from policy name (e.g. resource:map).
304  */
305  domain=UndefinedPolicyDomain;
306  for (q=policyname; *q != '\0'; q++)
307  {
308  if (*q != ':')
309  continue;
310  *q='\0';
312  MagickTrue,policyname);
313  (void) CopyMagickString(policyname,q+1,MagickPathExtent);
314  break;
315  }
316  /*
317  Search for policy tag.
318  */
322  if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
323  {
325  return(p);
326  }
327  while (p != (PolicyInfo *) NULL)
328  {
329  if ((domain == UndefinedPolicyDomain) || (p->domain == domain))
330  if (LocaleCompare(policyname,p->name) == 0)
331  break;
333  }
334  if (p != (PolicyInfo *) NULL)
338  return(p);
339 }
340 
341 /*
342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343 % %
344 % %
345 % %
346 % G e t P o l i c y I n f o L i s t %
347 % %
348 % %
349 % %
350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 %
352 % GetPolicyInfoList() returns any policies that match the specified pattern.
353 %
354 % The format of the GetPolicyInfoList function is:
355 %
356 % const PolicyInfo **GetPolicyInfoList(const char *pattern,
357 % size_t *number_policies,ExceptionInfo *exception)
358 %
359 % A description of each parameter follows:
360 %
361 % o pattern: Specifies a pointer to a text string containing a pattern.
362 %
363 % o number_policies: returns the number of policies in the list.
364 %
365 % o exception: return any errors or warnings in this structure.
366 %
367 */
368 MagickExport const PolicyInfo **GetPolicyInfoList(const char *pattern,
369  size_t *number_policies,ExceptionInfo *exception)
370 {
371  const PolicyInfo
372  **policies;
373 
374  const PolicyInfo
375  *p;
376 
377  ssize_t
378  i;
379 
380  /*
381  Allocate policy list.
382  */
383  assert(pattern != (char *) NULL);
384  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
385  assert(number_policies != (size_t *) NULL);
386  *number_policies=0;
387  p=GetPolicyInfo("*",exception);
388  if (p == (const PolicyInfo *) NULL)
389  return((const PolicyInfo **) NULL);
390  policies=(const PolicyInfo **) AcquireQuantumMemory((size_t)
391  GetNumberOfElementsInLinkedList(policy_cache)+1UL,sizeof(*policies));
392  if (policies == (const PolicyInfo **) NULL)
393  return((const PolicyInfo **) NULL);
394  /*
395  Generate policy list.
396  */
400  for (i=0; p != (const PolicyInfo *) NULL; )
401  {
402  if ((p->stealth == MagickFalse) &&
403  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
404  policies[i++]=p;
406  }
408  policies[i]=(PolicyInfo *) NULL;
409  *number_policies=(size_t) i;
410  return(policies);
411 }
412 
413 /*
414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
415 % %
416 % %
417 % %
418 % G e t P o l i c y L i s t %
419 % %
420 % %
421 % %
422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
423 %
424 % GetPolicyList() returns any policies that match the specified pattern.
425 %
426 % The format of the GetPolicyList function is:
427 %
428 % char **GetPolicyList(const char *pattern,size_t *number_policies,
429 % ExceptionInfo *exception)
430 %
431 % A description of each parameter follows:
432 %
433 % o pattern: a pointer to a text string containing a pattern.
434 %
435 % o number_policies: returns the number of policies in the list.
436 %
437 % o exception: return any errors or warnings in this structure.
438 %
439 */
440 
441 static char *AcquirePolicyString(const char *source,const size_t pad)
442 {
443  char
444  *destination;
445 
446  size_t
447  length;
448 
449  length=0;
450  if (source != (char *) NULL)
451  length+=strlen(source);
452  destination=(char *) NULL;
453  if (~length >= pad)
454  destination=(char *) AcquireQuantumMemory(length+pad,sizeof(*destination));
455  if (destination == (char *) NULL)
456  ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
457  if (source != (char *) NULL)
458  (void) memcpy(destination,source,length*sizeof(*destination));
459  destination[length]='\0';
460  return(destination);
461 }
462 
463 MagickExport char **GetPolicyList(const char *pattern,size_t *number_policies,
464  ExceptionInfo *exception)
465 {
466  char
467  **policies;
468 
469  const PolicyInfo
470  *p;
471 
472  ssize_t
473  i;
474 
475  /*
476  Allocate policy list.
477  */
478  assert(pattern != (char *) NULL);
479  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
480  assert(number_policies != (size_t *) NULL);
481  *number_policies=0;
482  p=GetPolicyInfo("*",exception);
483  if (p == (const PolicyInfo *) NULL)
484  return((char **) NULL);
485  policies=(char **) AcquireQuantumMemory((size_t)
486  GetNumberOfElementsInLinkedList(policy_cache)+1UL,sizeof(*policies));
487  if (policies == (char **) NULL)
488  return((char **) NULL);
489  /*
490  Generate policy list.
491  */
495  for (i=0; p != (const PolicyInfo *) NULL; )
496  {
497  if ((p->stealth == MagickFalse) &&
498  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
499  policies[i++]=AcquirePolicyString(p->name,1);
501  }
503  policies[i]=(char *) NULL;
504  *number_policies=(size_t) i;
505  return(policies);
506 }
507 
508 /*
509 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
510 % %
511 % %
512 % %
513 % G e t P o l i c y V a l u e %
514 % %
515 % %
516 % %
517 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
518 %
519 % GetPolicyValue() returns the value associated with the named policy.
520 %
521 % The format of the GetPolicyValue method is:
522 %
523 % char *GetPolicyValue(const char *name)
524 %
525 % A description of each parameter follows:
526 %
527 % o name: The name of the policy.
528 %
529 */
530 MagickExport char *GetPolicyValue(const char *name)
531 {
532  const char
533  *value;
534 
535  const PolicyInfo
536  *policy_info;
537 
539  *exception;
540 
541  assert(name != (const char *) NULL);
542  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
543  exception=AcquireExceptionInfo();
544  policy_info=GetPolicyInfo(name,exception);
545  exception=DestroyExceptionInfo(exception);
546  if (policy_info == (PolicyInfo *) NULL)
547  return((char *) NULL);
548  value=policy_info->value;
549  if ((value == (const char *) NULL) || (*value == '\0'))
550  return((char *) NULL);
551  return(AcquirePolicyString(value,1));
552 }
553 
554 /*
555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
556 % %
557 % %
558 % %
559 + I s P o l i c y C a c h e I n s t a n t i a t e d %
560 % %
561 % %
562 % %
563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564 %
565 % IsPolicyCacheInstantiated() determines if the policy list is instantiated.
566 % If not, it instantiates the list and returns it.
567 %
568 % The format of the IsPolicyInstantiated method is:
569 %
570 % MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *exception)
571 %
572 % A description of each parameter follows.
573 %
574 % o exception: return any errors or warnings in this structure.
575 %
576 */
578 {
579  if (policy_cache == (LinkedListInfo *) NULL)
580  {
581  if (policy_semaphore == (SemaphoreInfo *) NULL)
584  if (policy_cache == (LinkedListInfo *) NULL)
587  }
588  return(policy_cache != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
589 }
590 
591 /*
592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593 % %
594 % %
595 % %
596 % I s R i g h t s A u t h o r i z e d %
597 % %
598 % %
599 % %
600 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
601 %
602 % IsRightsAuthorized() returns MagickTrue if the policy authorizes the
603 % requested rights for the specified domain.
604 %
605 % The format of the IsRightsAuthorized method is:
606 %
607 % MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
608 % const PolicyRights rights,const char *pattern)
609 %
610 % A description of each parameter follows:
611 %
612 % o domain: the policy domain.
613 %
614 % o rights: the policy rights.
615 %
616 % o pattern: the coder, delegate, filter, or path pattern.
617 %
618 */
620  const PolicyRights rights,const char *pattern)
621 {
622  const PolicyInfo
623  *policy_info;
624 
626  *exception;
627 
629  authorized;
630 
631  PolicyInfo
632  *p;
633 
634  if (IsEventLogging() != MagickFalse)
636  "Domain: %s; rights=%s; pattern=\"%s\" ...",
639  exception=AcquireExceptionInfo();
640  policy_info=GetPolicyInfo("*",exception);
641  exception=DestroyExceptionInfo(exception);
642  if (policy_info == (PolicyInfo *) NULL)
643  return(MagickTrue);
644  authorized=MagickTrue;
648  while (p != (PolicyInfo *) NULL)
649  {
650  if ((p->domain == domain) &&
652  {
653  if ((rights & ReadPolicyRights) != 0)
654  authorized=(p->rights & ReadPolicyRights) != 0 ? MagickTrue :
655  MagickFalse;
656  if ((rights & WritePolicyRights) != 0)
657  authorized=(p->rights & WritePolicyRights) != 0 ? MagickTrue :
658  MagickFalse;
659  if ((rights & ExecutePolicyRights) != 0)
660  authorized=(p->rights & ExecutePolicyRights) != 0 ? MagickTrue :
661  MagickFalse;
662  }
664  }
666  return(authorized);
667 }
668 
669 /*
670 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
671 % %
672 % %
673 % %
674 % L i s t P o l i c y I n f o %
675 % %
676 % %
677 % %
678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679 %
680 % ListPolicyInfo() lists policies to the specified file.
681 %
682 % The format of the ListPolicyInfo method is:
683 %
684 % MagickBooleanType ListPolicyInfo(FILE *file,ExceptionInfo *exception)
685 %
686 % A description of each parameter follows.
687 %
688 % o file: List policy names to this file handle.
689 %
690 % o exception: return any errors or warnings in this structure.
691 %
692 */
694  ExceptionInfo *exception)
695 {
696  const char
697  *path,
698  *domain;
699 
700  const PolicyInfo
701  **policy_info;
702 
703  ssize_t
704  i;
705 
706  size_t
707  number_policies;
708 
709  /*
710  List name and attributes of each policy in the list.
711  */
712  if (file == (const FILE *) NULL)
713  file=stdout;
714  policy_info=GetPolicyInfoList("*",&number_policies,exception);
715  if (policy_info == (const PolicyInfo **) NULL)
716  return(MagickFalse);
717  path=(const char *) NULL;
718  for (i=0; i < (ssize_t) number_policies; i++)
719  {
720  if (policy_info[i]->stealth != MagickFalse)
721  continue;
722  if (((path == (const char *) NULL) ||
723  (LocaleCompare(path,policy_info[i]->path) != 0)) &&
724  (policy_info[i]->path != (char *) NULL))
725  (void) FormatLocaleFile(file,"\nPath: %s\n",policy_info[i]->path);
726  path=policy_info[i]->path;
728  policy_info[i]->domain);
729  (void) FormatLocaleFile(file," Policy: %s\n",domain);
730  if ((policy_info[i]->domain == CachePolicyDomain) ||
731  (policy_info[i]->domain == ResourcePolicyDomain) ||
732  (policy_info[i]->domain == SystemPolicyDomain))
733  {
734  if (policy_info[i]->name != (char *) NULL)
735  (void) FormatLocaleFile(file," name: %s\n",policy_info[i]->name);
736  if (policy_info[i]->value != (char *) NULL)
737  (void) FormatLocaleFile(file," value: %s\n",policy_info[i]->value);
738  }
739  else
740  {
741  (void) FormatLocaleFile(file," rights: ");
742  if (policy_info[i]->rights == NoPolicyRights)
743  (void) FormatLocaleFile(file,"None ");
744  if ((policy_info[i]->rights & ReadPolicyRights) != 0)
745  (void) FormatLocaleFile(file,"Read ");
746  if ((policy_info[i]->rights & WritePolicyRights) != 0)
747  (void) FormatLocaleFile(file,"Write ");
748  if ((policy_info[i]->rights & ExecutePolicyRights) != 0)
749  (void) FormatLocaleFile(file,"Execute ");
750  (void) FormatLocaleFile(file,"\n");
751  if (policy_info[i]->pattern != (char *) NULL)
752  (void) FormatLocaleFile(file," pattern: %s\n",
753  policy_info[i]->pattern);
754  }
755  }
756  policy_info=(const PolicyInfo **) RelinquishMagickMemory((void *)
757  policy_info);
758  (void) fflush(file);
759  return(MagickTrue);
760 }
761 
762 /*
763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
764 % %
765 % %
766 % %
767 + L o a d P o l i c y C a c h e %
768 % %
769 % %
770 % %
771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
772 %
773 % LoadPolicyCache() loads the policy configurations which provides a mapping
774 % between policy attributes and a policy domain.
775 %
776 % The format of the LoadPolicyCache method is:
777 %
778 % MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,const char *xml,
779 % const char *filename,const size_t depth,ExceptionInfo *exception)
780 %
781 % A description of each parameter follows:
782 %
783 % o xml: The policy list in XML format.
784 %
785 % o filename: The policy list filename.
786 %
787 % o depth: depth of <include /> statements.
788 %
789 % o exception: return any errors or warnings in this structure.
790 %
791 */
792 static MagickBooleanType LoadPolicyCache(LinkedListInfo *cache,const char *xml,
793  const char *filename,const size_t depth,ExceptionInfo *exception)
794 {
795  char
796  keyword[MagickPathExtent],
797  *token;
798 
799  const char
800  *q;
801 
803  status;
804 
805  PolicyInfo
806  *policy_info;
807 
808  size_t
809  extent;
810 
811  /*
812  Load the policy map file.
813  */
815  "Loading policy file \"%s\" ...",filename);
816  if (xml == (char *) NULL)
817  return(MagickFalse);
818  status=MagickTrue;
819  policy_info=(PolicyInfo *) NULL;
821  extent=strlen(token)+MagickPathExtent;
822  for (q=(const char *) xml; *q != '\0'; )
823  {
824  /*
825  Interpret XML.
826  */
827  (void) GetNextToken(q,&q,extent,token);
828  if (*token == '\0')
829  break;
830  (void) CopyMagickString(keyword,token,MagickPathExtent);
831  if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
832  {
833  /*
834  Docdomain element.
835  */
836  while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
837  (void) GetNextToken(q,&q,extent,token);
838  continue;
839  }
840  if (LocaleNCompare(keyword,"<!--",4) == 0)
841  {
842  /*
843  Comment element.
844  */
845  while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
846  (void) GetNextToken(q,&q,extent,token);
847  continue;
848  }
849  if (LocaleCompare(keyword,"<include") == 0)
850  {
851  /*
852  Include element.
853  */
854  while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
855  {
856  (void) CopyMagickString(keyword,token,MagickPathExtent);
857  (void) GetNextToken(q,&q,extent,token);
858  if (*token != '=')
859  continue;
860  (void) GetNextToken(q,&q,extent,token);
861  if (LocaleCompare(keyword,"file") == 0)
862  {
863  if (depth > MagickMaxRecursionDepth)
864  (void) ThrowMagickException(exception,GetMagickModule(),
865  ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
866  else
867  {
868  char
869  path[MagickPathExtent],
870  *file_xml;
871 
872  GetPathComponent(filename,HeadPath,path);
873  if (*path != '\0')
876  if (*token == *DirectorySeparator)
877  (void) CopyMagickString(path,token,MagickPathExtent);
878  else
879  (void) ConcatenateMagickString(path,token,MagickPathExtent);
880  file_xml=FileToXML(path,~0UL);
881  if (file_xml != (char *) NULL)
882  {
883  status&=LoadPolicyCache(cache,file_xml,path,
884  depth+1,exception);
885  file_xml=DestroyString(file_xml);
886  }
887  }
888  }
889  }
890  continue;
891  }
892  if (LocaleCompare(keyword,"<policy") == 0)
893  {
894  /*
895  Policy element.
896  */
897  policy_info=(PolicyInfo *) AcquireCriticalMemory(sizeof(*policy_info));
898  (void) memset(policy_info,0,sizeof(*policy_info));
899  policy_info->path=AcquirePolicyString(filename,1);
900  policy_info->exempt=MagickFalse;
901  policy_info->signature=MagickCoreSignature;
902  continue;
903  }
904  if (policy_info == (PolicyInfo *) NULL)
905  continue;
906  if ((LocaleCompare(keyword,"/>") == 0) ||
907  (LocaleCompare(keyword,"</policy>") == 0))
908  {
909  status=AppendValueToLinkedList(cache,policy_info);
910  if (status == MagickFalse)
911  (void) ThrowMagickException(exception,GetMagickModule(),
912  ResourceLimitError,"MemoryAllocationFailed","`%s'",
913  policy_info->name);
914  policy_info=(PolicyInfo *) NULL;
915  continue;
916  }
917  (void) GetNextToken(q,(const char **) NULL,extent,token);
918  if (*token != '=')
919  continue;
920  (void) GetNextToken(q,&q,extent,token);
921  (void) GetNextToken(q,&q,extent,token);
922  switch (*keyword)
923  {
924  case 'D':
925  case 'd':
926  {
927  if (LocaleCompare((char *) keyword,"domain") == 0)
928  {
929  policy_info->domain=(PolicyDomain) ParseCommandOption(
931  break;
932  }
933  break;
934  }
935  case 'N':
936  case 'n':
937  {
938  if (LocaleCompare((char *) keyword,"name") == 0)
939  {
940  policy_info->name=AcquirePolicyString(token,1);
941  break;
942  }
943  break;
944  }
945  case 'P':
946  case 'p':
947  {
948  if (LocaleCompare((char *) keyword,"pattern") == 0)
949  {
950  policy_info->pattern=AcquirePolicyString(token,1);
951  break;
952  }
953  break;
954  }
955  case 'R':
956  case 'r':
957  {
958  if (LocaleCompare((char *) keyword,"rights") == 0)
959  {
960  policy_info->rights=(PolicyRights) ParseCommandOption(
962  break;
963  }
964  break;
965  }
966  case 'S':
967  case 's':
968  {
969  if (LocaleCompare((char *) keyword,"stealth") == 0)
970  {
971  policy_info->stealth=IsStringTrue(token);
972  break;
973  }
974  break;
975  }
976  case 'V':
977  case 'v':
978  {
979  if (LocaleCompare((char *) keyword,"value") == 0)
980  {
981  policy_info->value=AcquirePolicyString(token,1);
982  break;
983  }
984  break;
985  }
986  default:
987  break;
988  }
989  }
990  token=(char *) RelinquishMagickMemory(token);
991  return(status != 0 ? MagickTrue : MagickFalse);
992 }
993 
994 /*
995 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
996 % %
997 % %
998 % %
999 + P o l i c y C o m p o n e n t G e n e s i s %
1000 % %
1001 % %
1002 % %
1003 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1004 %
1005 % PolicyComponentGenesis() instantiates the policy component.
1006 %
1007 % The format of the PolicyComponentGenesis method is:
1008 %
1009 % MagickBooleanType PolicyComponentGenesis(void)
1010 %
1011 */
1013 {
1014  if (policy_semaphore == (SemaphoreInfo *) NULL)
1016  return(MagickTrue);
1017 }
1018 
1019 /*
1020 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1021 % %
1022 % %
1023 % %
1024 + P o l i c y C o m p o n e n t T e r m i n u s %
1025 % %
1026 % %
1027 % %
1028 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1029 %
1030 % PolicyComponentTerminus() destroys the policy component.
1031 %
1032 % The format of the PolicyComponentTerminus method is:
1033 %
1034 % PolicyComponentTerminus(void)
1035 %
1036 */
1037 
1038 static void *DestroyPolicyElement(void *policy_info)
1039 {
1040  PolicyInfo
1041  *p;
1042 
1043  p=(PolicyInfo *) policy_info;
1044  if (p->exempt == MagickFalse)
1045  {
1046  if (p->value != (char *) NULL)
1047  p->value=DestroyString(p->value);
1048  if (p->pattern != (char *) NULL)
1049  p->pattern=DestroyString(p->pattern);
1050  if (p->name != (char *) NULL)
1051  p->name=DestroyString(p->name);
1052  if (p->path != (char *) NULL)
1053  p->path=DestroyString(p->path);
1054  }
1056  return((void *) NULL);
1057 }
1058 
1060 {
1061  if (policy_semaphore == (SemaphoreInfo *) NULL)
1064  if (policy_cache != (LinkedListInfo *) NULL)
1068 }
1069 
1070 /*
1071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1072 % %
1073 % %
1074 % %
1075 % S e t M a g i c k S e c u r i t y P o l i c y %
1076 % %
1077 % %
1078 % %
1079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1080 %
1081 % SetMagickSecurityPolicy() sets the ImageMagick security policy. It returns
1082 % MagickFalse if the policy is already set or if the policy does not parse.
1083 %
1084 % The format of the SetMagickSecurityPolicy method is:
1085 %
1086 % MagickBooleanType SetMagickSecurityPolicy(const char *policy,
1087 % ExceptionInfo *exception)
1088 %
1089 % A description of each parameter follows:
1090 %
1091 % o policy: the security policy in the XML format.
1092 %
1093 % o exception: return any errors or warnings in this structure.
1094 %
1095 */
1097  ExceptionInfo *exception)
1098 {
1099  PolicyInfo
1100  *p;
1101 
1103  status;
1104 
1105  assert(exception != (ExceptionInfo *) NULL);
1106  if (policy == (const char *) NULL)
1107  return(MagickFalse);
1108  if (IsPolicyCacheInstantiated(exception) == MagickFalse)
1109  return(MagickFalse);
1113  if ((p != (PolicyInfo *) NULL) && (p->domain != UndefinedPolicyDomain))
1114  {
1116  return(MagickFalse);
1117  }
1119  status=LoadPolicyCache(policy_cache,policy,"[user-policy]",0,exception);
1120  if (status == MagickFalse)
1121  return(MagickFalse);
1122  return(ResourceComponentGenesis());
1123 }
1124 
1125 /*
1126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1127 % %
1128 % %
1129 % %
1130 % S e t M a g i c k S e c u r i t y P o l i c y V a l u e %
1131 % %
1132 % %
1133 % %
1134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1135 %
1136 % SetMagickSecurityPolicyValue() sets a value associated with an ImageMagick
1137 % security policy. For most policies, the value must be less than any value
1138 % set by the security policy configuration file (i.e. policy.xml). It returns
1139 % MagickFalse if the policy cannot be modified or if the policy does not parse.
1140 %
1141 % The format of the SetMagickSecurityPolicyValue method is:
1142 %
1143 % MagickBooleanType SetMagickSecurityPolicyValue(
1144 % const PolicyDomain domain,const char *name,const char *value,
1145 % ExceptionInfo *exception)
1146 %
1147 % A description of each parameter follows:
1148 %
1149 % o domain: the domain of the policy (e.g. system, resource).
1150 %
1151 % o name: the name of the policy.
1152 %
1153 % o value: the value to set the policy to.
1154 %
1155 % o exception: return any errors or warnings in this structure.
1156 %
1157 */
1158 
1160  const char *name,const char *value)
1161 {
1163  status;
1164 
1165  PolicyInfo
1166  *p;
1167 
1168  status=MagickTrue;
1172  while (p != (PolicyInfo *) NULL)
1173  {
1174  if ((p->domain == domain) && (LocaleCompare(name,p->name) == 0))
1175  break;
1177  }
1178  if (p != (PolicyInfo *) NULL)
1179  {
1180  if (p->value != (char *) NULL)
1181  p->value=DestroyString(p->value);
1182  }
1183  else
1184  {
1185  p=(PolicyInfo *) AcquireCriticalMemory(sizeof(*p));
1186  (void) memset(p,0,sizeof(*p));
1187  p->exempt=MagickFalse;
1189  p->domain=domain;
1190  p->name=AcquirePolicyString(name,1);
1192  }
1193  p->value=AcquirePolicyString(value,1);
1195  if (status == MagickFalse)
1197  return(status);
1198 }
1199 
1201  const PolicyDomain domain,const char *name,const char *value,
1202  ExceptionInfo *exception)
1203 {
1204  char
1205  *current_value;
1206 
1207  magick_unreferenced(exception);
1208  assert(exception != (ExceptionInfo *) NULL);
1209  if ((name == (const char *) NULL) || (value == (const char *) NULL))
1210  return(MagickFalse);
1211  switch(domain)
1212  {
1213  case CachePolicyDomain:
1214  {
1215  if (LocaleCompare(name,"memory-map") == 0)
1216  {
1217  if (LocaleCompare(value,"anonymous") != 0)
1218  return(MagickFalse);
1221  return(SetPolicyValue(domain,name,value));
1222  }
1223  if (LocaleCompare(name,"synchronize") == 0)
1224  return(SetPolicyValue(domain,name,value));
1225  break;
1226  }
1227  case ResourcePolicyDomain:
1228  {
1229  ssize_t
1230  type;
1231 
1232  if (LocaleCompare(name,"temporary-path") == 0)
1233  return(SetPolicyValue(domain,name,value));
1235  if (type >= 0)
1236  {
1238  limit;
1239 
1240  limit=MagickResourceInfinity;
1241  if (LocaleCompare("unlimited",value) != 0)
1242  limit=StringToMagickSizeType(value,100.0);
1243  return(SetMagickResourceLimit((ResourceType) type,limit));
1244  }
1245  break;
1246  }
1247  case SystemPolicyDomain:
1248  {
1249  if (LocaleCompare(name,"font") == 0)
1250  return(SetPolicyValue(domain,name,value));
1251  if (LocaleCompare(name,"max-memory-request") == 0)
1252  {
1253  current_value=GetPolicyValue("system:max-memory-request");
1254  if ((current_value == (char *) NULL) ||
1255  (StringToSizeType(value,100.0) < StringToSizeType(current_value,100.0)))
1256  {
1257  if (current_value != (char *) NULL)
1258  current_value=DestroyString(current_value);
1260  return(SetPolicyValue(domain,name,value));
1261  }
1262  if (current_value != (char *) NULL)
1263  current_value=DestroyString(current_value);
1264  }
1265  if (LocaleCompare(name,"memory-map") == 0)
1266  {
1267  if (LocaleCompare(value,"anonymous") != 0)
1268  return(MagickFalse);
1270  return(SetPolicyValue(domain,name,value));
1271  }
1272  if (LocaleCompare(name,"precision") == 0)
1273  {
1275  return(SetPolicyValue(domain,name,value));
1276  }
1277  if (LocaleCompare(name,"shred") == 0)
1278  {
1279  current_value=GetPolicyValue("system:shred");
1280  if ((current_value == (char *) NULL) ||
1281  (StringToInteger(value) > StringToInteger(current_value)))
1282  {
1283  if (current_value != (char *) NULL)
1284  current_value=DestroyString(current_value);
1285  return(SetPolicyValue(domain,name,value));
1286  }
1287  if (current_value != (char *) NULL)
1288  current_value=DestroyString(current_value);
1289  }
1290  break;
1291  }
1292  case CoderPolicyDomain:
1293  case DelegatePolicyDomain:
1294  case FilterPolicyDomain:
1295  case ModulePolicyDomain:
1296  case PathPolicyDomain:
1297  default:
1298  break;
1299  }
1300  return(MagickFalse);
1301 }
MagickBooleanType stealth
Definition: policy.c:95
char * value
Definition: policy.c:90
MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
Definition: resource.c:1143
#define MagickMaxRecursionDepth
Definition: studio.h:352
static size_t StringToSizeType(const char *string, const double interval)
MagickExport const PolicyInfo ** GetPolicyInfoList(const char *pattern, size_t *number_policies, ExceptionInfo *exception)
Definition: policy.c:368
MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain, const PolicyRights rights, const char *pattern)
Definition: policy.c:619
MagickExport size_t ConcatenateMagickString(char *magick_restrict destination, const char *magick_restrict source, const size_t length)
Definition: string.c:392
MagickExport MagickBooleanType ListPolicyInfo(FILE *file, ExceptionInfo *exception)
Definition: policy.c:693
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:449
MagickExport void ResetLinkedListIterator(LinkedListInfo *list_info)
Definition: linked-list.c:959
MagickExport ssize_t ParseCommandOption(const CommandOption option, const MagickBooleanType list, const char *options)
Definition: option.c:3031
static SemaphoreInfo * policy_semaphore
Definition: policy.c:134
SemaphoreInfo * semaphore
Definition: policy.c:100
PolicyRights
Definition: policy.h:41
#define ThrowFatalException(severity, tag)
static int StringToInteger(const char *magick_restrict value)
MagickExport LinkedListInfo * DestroyLinkedList(LinkedListInfo *list_info, void *(*relinquish_value)(void *))
Definition: linked-list.c:219
struct _PolicyMapInfo PolicyMapInfo
char * name
Definition: policy.c:90
MagickBooleanType debug
Definition: policy.c:95
MagickExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition: semaphore.c:192
MagickExport MagickBooleanType InsertValueInLinkedList(LinkedListInfo *list_info, const size_t index, const void *value)
Definition: linked-list.c:447
const char * name
Definition: policy.c:115
char * pattern
Definition: policy.c:90
MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type, const MagickSizeType limit)
Definition: resource.c:1352
static PolicyInfo * GetPolicyInfo(const char *name, ExceptionInfo *exception)
Definition: policy.c:272
MagickExport ExceptionInfo * AcquireExceptionInfo(void)
Definition: exception.c:115
MagickExport MagickBooleanType AppendValueToLinkedList(LinkedListInfo *list_info, const void *value)
Definition: linked-list.c:111
MagickExport size_t CopyMagickString(char *magick_restrict destination, const char *magick_restrict source, const size_t length)
Definition: string.c:719
MagickExport void * RemoveElementByValueFromLinkedList(LinkedListInfo *list_info, const void *value)
Definition: linked-list.c:756
static LinkedListInfo * policy_cache
Definition: policy.c:131
MagickPrivate MagickBooleanType PolicyComponentGenesis(void)
Definition: policy.c:1012
MagickExport MagickBooleanType SetMagickSecurityPolicyValue(const PolicyDomain domain, const char *name, const char *value, ExceptionInfo *exception)
Definition: policy.c:1200
Definition: log.h:52
static const PolicyMapInfo PolicyMap[]
Definition: policy.c:124
MagickExport void * GetNextValueInLinkedList(LinkedListInfo *list_info)
Definition: linked-list.c:305
size_t signature
Definition: policy.c:103
#define MagickCoreSignature
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:293
MagickExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition: string.c:1168
MagickExport LinkedListInfo * GetConfigureOptions(const char *filename, ExceptionInfo *exception)
Definition: configure.c:642
static MagickBooleanType LoadPolicyCache(LinkedListInfo *, const char *, const char *, const size_t, ExceptionInfo *)
Definition: policy.c:792
MagickExport void GetPathComponent(const char *path, PathType type, char *component)
Definition: utility.c:1223
MagickExport ssize_t FormatLocaleFile(FILE *file, const char *magick_restrict format,...)
Definition: locale.c:372
MagickBooleanType
Definition: magick-type.h:173
#define DirectorySeparator
Definition: studio.h:267
unsigned int MagickStatusType
Definition: magick-type.h:129
MagickPrivate void ResetMagickPrecision(void)
Definition: magick.c:1718
MagickExport MagickBooleanType GlobExpression(const char *magick_restrict expression, const char *magick_restrict pattern, const MagickBooleanType case_insensitive)
Definition: token.c:355
MagickExport const char * CommandOptionToMnemonic(const CommandOption option, const ssize_t type)
Definition: option.c:2740
MagickExport void * AcquireCriticalMemory(const size_t size)
Definition: memory.c:626
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:665
MagickExport int LocaleNCompare(const char *p, const char *q, const size_t length)
Definition: locale.c:1527
MagickExport magick_hot_spot size_t GetNextToken(const char *magick_restrict start, const char **magick_restrict end, const size_t extent, char *magick_restrict token)
Definition: token.c:174
size_t MagickSizeType
Definition: magick-type.h:138
#define MagickPathExtent
MagickExport MagickBooleanType IsStringTrue(const char *value)
Definition: string.c:1378
MagickExport MagickBooleanType IsEventLogging(void)
Definition: log.c:725
static MagickBooleanType SetPolicyValue(const PolicyDomain domain, const char *name, const char *value)
Definition: policy.c:1159
PolicyRights rights
Definition: policy.c:87
MagickExport char ** GetPolicyList(const char *pattern, size_t *number_policies, ExceptionInfo *exception)
Definition: policy.c:463
MagickPrivate void ResetCacheAnonymousMemory(void)
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
Definition: exception.c:1145
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1660
MagickExport LinkedListInfo * NewLinkedList(const size_t capacity)
Definition: linked-list.c:713
MagickPrivate void ResetStreamAnonymousMemory(void)
PolicyDomain
Definition: policy.h:28
ResourceType
Definition: resource_.h:25
MagickExport int LocaleCompare(const char *p, const char *q)
Definition: locale.c:1403
#define GetMagickModule()
Definition: log.h:28
MagickExport const char * GetStringInfoPath(const StringInfo *string_info)
Definition: string.c:1255
MagickBooleanType exempt
Definition: policy.c:95
#define PolicyFilename
Definition: policy.c:73
#define MagickResourceInfinity
Definition: resource_.h:41
MagickExport MagickBooleanType SetMagickSecurityPolicy(const char *policy, ExceptionInfo *exception)
Definition: policy.c:1096
MagickExport char * DestroyString(char *string)
Definition: string.c:776
MagickExport void * AcquireMagickMemory(const size_t size)
Definition: memory.c:552
MagickExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:98
const char * pattern
Definition: policy.c:115
MagickExport size_t GetNumberOfElementsInLinkedList(const LinkedListInfo *list_info)
Definition: linked-list.c:348
static MagickSizeType StringToMagickSizeType(const char *string, const double interval)
static LinkedListInfo * AcquirePolicyCache(const char *filename, ExceptionInfo *exception)
Definition: policy.c:170
MagickExport char * GetPolicyValue(const char *name)
Definition: policy.c:530
const PolicyDomain domain
Definition: policy.c:109
PolicyDomain domain
Definition: policy.c:84
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1162
#define magick_unreferenced(x)
const PolicyRights rights
Definition: policy.c:112
#define MagickPrivate
MagickPrivate char * FileToXML(const char *, const size_t)
Definition: xml-tree.c:598
#define MagickExport
MagickPrivate void PolicyComponentTerminus(void)
Definition: policy.c:1059
const char * value
Definition: policy.c:115
static char * AcquirePolicyString(const char *source, const size_t pad)
Definition: policy.c:441
static void * DestroyPolicyElement(void *policy_info)
Definition: policy.c:1038
MagickPrivate void ResetMaxMemoryRequest(void)
char * path
Definition: policy.c:81
MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:351
MagickExport LinkedListInfo * DestroyConfigureOptions(LinkedListInfo *options)
Definition: configure.c:314
MagickPrivate void ResetVirtualAnonymousMemory(void)
Definition: memory.c:1335
MagickExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition: exception.c:418
static MagickBooleanType IsPolicyCacheInstantiated(ExceptionInfo *)
Definition: policy.c:577