2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 % PPPP OOO L IIIII CCCC Y Y %
9 % P OOO LLLLL IIIII CCCC Y %
12 % MagickCore Policy Methods %
19 % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
25 % http://www.imagemagick.org/script/license.php %
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. %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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).
43 #include "MagickCore/studio.h"
44 #include "MagickCore/client.h"
45 #include "MagickCore/configure.h"
46 #include "MagickCore/configure-private.h"
47 #include "MagickCore/exception.h"
48 #include "MagickCore/exception-private.h"
49 #include "MagickCore/memory_.h"
50 #include "MagickCore/monitor.h"
51 #include "MagickCore/monitor-private.h"
52 #include "MagickCore/option.h"
53 #include "MagickCore/policy.h"
54 #include "MagickCore/policy-private.h"
55 #include "MagickCore/semaphore.h"
56 #include "MagickCore/string_.h"
57 #include "MagickCore/token.h"
58 #include "MagickCore/utility.h"
59 #include "MagickCore/utility-private.h"
60 #include "MagickCore/xml-tree.h"
65 #define PolicyFilename "policy.xml"
98 typedef struct _PolicyMapInfo
115 static const PolicyMapInfo
118 { UndefinedPolicyDomain, UndefinedPolicyRights, (const char *) NULL,
119 (const char *) NULL, (const char *) NULL }
122 static LinkedListInfo
123 *policy_list = (LinkedListInfo *) NULL;
126 *policy_semaphore = (SemaphoreInfo *) NULL;
128 static volatile MagickBooleanType
129 instantiate_policy = MagickFalse;
132 Forward declarations.
134 static MagickBooleanType
135 InitializePolicyList(ExceptionInfo *),
136 LoadPolicyLists(const char *,ExceptionInfo *);
139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143 + G e t P o l i c y I n f o %
147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149 % GetPolicyInfo() searches the policy list for the specified name and if found
150 % returns attributes for that policy.
152 % The format of the GetPolicyInfo method is:
154 % PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
156 % A description of each parameter follows:
158 % o name: the policy name.
160 % o exception: return any errors or warnings in this structure.
163 static PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
166 policyname[MaxTextExtent];
174 assert(exception != (ExceptionInfo *) NULL);
175 if ((policy_list == (LinkedListInfo *) NULL) ||
176 (instantiate_policy == MagickFalse))
177 if (InitializePolicyList(exception) == MagickFalse)
178 return((PolicyInfo *) NULL);
179 if ((policy_list == (LinkedListInfo *) NULL) ||
180 (IsLinkedListEmpty(policy_list) != MagickFalse))
181 return((PolicyInfo *) NULL);
182 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
183 return((PolicyInfo *) GetValueFromLinkedList(policy_list,0));
185 Strip names of whitespace.
187 (void) CopyMagickString(policyname,name,MaxTextExtent);
188 for (q=policyname; *q != '\0'; q++)
190 if (isspace((int) ((unsigned char) *q)) == 0)
192 (void) CopyMagickString(q,q+1,MaxTextExtent);
196 Search for policy tag.
198 LockSemaphoreInfo(policy_semaphore);
199 ResetLinkedListIterator(policy_list);
200 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
201 while (p != (PolicyInfo *) NULL)
203 if (LocaleCompare(policyname,p->name) == 0)
205 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
207 if (p != (PolicyInfo *) NULL)
208 (void) InsertValueInLinkedList(policy_list,0,
209 RemoveElementByValueFromLinkedList(policy_list,p));
210 UnlockSemaphoreInfo(policy_semaphore);
215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
219 % G e t P o l i c y I n f o L i s t %
223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
225 % GetPolicyInfoList() returns any policies that match the specified pattern.
227 % The format of the GetPolicyInfoList function is:
229 % const PolicyInfo **GetPolicyInfoList(const char *pattern,
230 % size_t *number_policies,ExceptionInfo *exception)
232 % A description of each parameter follows:
234 % o pattern: Specifies a pointer to a text string containing a pattern.
236 % o number_policies: returns the number of policies in the list.
238 % o exception: return any errors or warnings in this structure.
241 MagickExport const PolicyInfo **GetPolicyInfoList(const char *pattern,
242 size_t *number_policies,ExceptionInfo *exception)
247 register const PolicyInfo
254 Allocate policy list.
256 assert(pattern != (char *) NULL);
257 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
258 assert(number_policies != (size_t *) NULL);
260 p=GetPolicyInfo("*",exception);
261 if (p == (const PolicyInfo *) NULL)
262 return((const PolicyInfo **) NULL);
263 policies=(const PolicyInfo **) AcquireQuantumMemory((size_t)
264 GetNumberOfElementsInLinkedList(policy_list)+1UL,sizeof(*policies));
265 if (policies == (const PolicyInfo **) NULL)
266 return((const PolicyInfo **) NULL);
268 Generate policy list.
270 LockSemaphoreInfo(policy_semaphore);
271 ResetLinkedListIterator(policy_list);
272 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
273 for (i=0; p != (const PolicyInfo *) NULL; )
275 if ((p->stealth == MagickFalse) &&
276 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
278 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
280 UnlockSemaphoreInfo(policy_semaphore);
281 policies[i]=(PolicyInfo *) NULL;
282 *number_policies=(size_t) i;
287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291 % G e t P o l i c y L i s t %
295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297 % GetPolicyList() returns any policies that match the specified pattern.
299 % The format of the GetPolicyList function is:
301 % char **GetPolicyList(const char *pattern,size_t *number_policies,
302 % ExceptionInfo *exception)
304 % A description of each parameter follows:
306 % o pattern: a pointer to a text string containing a pattern.
308 % o number_policies: returns the number of policies in the list.
310 % o exception: return any errors or warnings in this structure.
313 MagickExport char **GetPolicyList(const char *pattern,
314 size_t *number_policies,ExceptionInfo *exception)
319 register const PolicyInfo
326 Allocate policy list.
328 assert(pattern != (char *) NULL);
329 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
330 assert(number_policies != (size_t *) NULL);
332 p=GetPolicyInfo("*",exception);
333 if (p == (const PolicyInfo *) NULL)
334 return((char **) NULL);
335 policies=(char **) AcquireQuantumMemory((size_t)
336 GetNumberOfElementsInLinkedList(policy_list)+1UL,sizeof(*policies));
337 if (policies == (char **) NULL)
338 return((char **) NULL);
340 Generate policy list.
342 LockSemaphoreInfo(policy_semaphore);
343 ResetLinkedListIterator(policy_list);
344 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
345 for (i=0; p != (const PolicyInfo *) NULL; )
347 if ((p->stealth == MagickFalse) &&
348 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
349 policies[i++]=ConstantString(p->name);
350 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
352 UnlockSemaphoreInfo(policy_semaphore);
353 policies[i]=(char *) NULL;
354 *number_policies=(size_t) i;
359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
363 % G e t P o l i c y V a l u e %
367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
369 % GetPolicyValue() returns the value associated with the named policy.
371 % The format of the GetPolicyValue method is:
373 % char *GetPolicyValue(const char *name)
375 % A description of each parameter follows:
377 % o policy_info: The policy info.
380 MagickExport char *GetPolicyValue(const char *name)
391 assert(name != (const char *) NULL);
392 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
393 exception=AcquireExceptionInfo();
394 policy_info=GetPolicyInfo(name,exception);
395 exception=DestroyExceptionInfo(exception);
396 if (policy_info == (PolicyInfo *) NULL)
397 return((char *) NULL);
398 value=policy_info->value;
399 if ((value == (const char *) NULL) || (*value == '\0'))
400 return((char *) NULL);
401 return(ConstantString(value));
405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
409 + I n i t i a l i z e P o l i c y L i s t %
413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
415 % InitializePolicyList() initializes the policy list.
417 % The format of the InitializePolicyList method is:
419 % MagickBooleanType InitializePolicyList(ExceptionInfo *exception)
421 % A description of each parameter follows.
423 % o exception: return any errors or warnings in this structure.
426 static MagickBooleanType InitializePolicyList(ExceptionInfo *exception)
428 if ((policy_list == (LinkedListInfo *) NULL) &&
429 (instantiate_policy == MagickFalse))
431 if (policy_semaphore == (SemaphoreInfo *) NULL)
432 AcquireSemaphoreInfo(&policy_semaphore);
433 LockSemaphoreInfo(policy_semaphore);
434 if ((policy_list == (LinkedListInfo *) NULL) &&
435 (instantiate_policy == MagickFalse))
437 (void) LoadPolicyLists(PolicyFilename,exception);
438 instantiate_policy=MagickTrue;
440 UnlockSemaphoreInfo(policy_semaphore);
442 return(policy_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450 % I s R i g h t s A u t h o r i z e d %
454 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456 % IsRightsAuthorized() returns MagickTrue if the policy authorizes the
457 % requested rights for the specified domain.
459 % The format of the IsRightsAuthorized method is:
461 % MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
462 % const PolicyRights rights,const char *pattern)
464 % A description of each parameter follows:
466 % o domain: the policy domain.
468 % o rights: the policy rights.
470 % o pattern: the coder, delegate, filter, or path pattern.
473 MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
474 const PolicyRights rights,const char *pattern)
488 (void) LogMagickEvent(PolicyEvent,GetMagickModule(),
489 "Domain: %s; rights=%s; pattern=\"%s\" ...",
490 CommandOptionToMnemonic(MagickPolicyDomainOptions,domain),
491 CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),pattern);
492 exception=AcquireExceptionInfo();
493 policy_info=GetPolicyInfo("*",exception);
494 exception=DestroyExceptionInfo(exception);
495 if (policy_info == (PolicyInfo *) NULL)
497 authorized=MagickTrue;
498 LockSemaphoreInfo(policy_semaphore);
499 ResetLinkedListIterator(policy_list);
500 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
501 while ((p != (PolicyInfo *) NULL) && (authorized != MagickFalse))
503 if ((p->domain == domain) &&
504 (GlobExpression(pattern,p->pattern,MagickFalse) != MagickFalse))
506 if (((rights & ReadPolicyRights) != 0) &&
507 ((p->rights & ReadPolicyRights) == 0))
508 authorized=MagickFalse;
509 if (((rights & WritePolicyRights) != 0) &&
510 ((p->rights & WritePolicyRights) == 0))
511 authorized=MagickFalse;
512 if (((rights & ExecutePolicyRights) != 0) &&
513 ((p->rights & ExecutePolicyRights) == 0))
514 authorized=MagickFalse;
516 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
518 UnlockSemaphoreInfo(policy_semaphore);
523 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
527 % L i s t P o l i c y I n f o %
531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
533 % ListPolicyInfo() lists policies to the specified file.
535 % The format of the ListPolicyInfo method is:
537 % MagickBooleanType ListPolicyInfo(FILE *file,ExceptionInfo *exception)
539 % A description of each parameter follows.
541 % o file: List policy names to this file handle.
543 % o exception: return any errors or warnings in this structure.
546 MagickExport MagickBooleanType ListPolicyInfo(FILE *file,
547 ExceptionInfo *exception)
563 List name and attributes of each policy in the list.
565 if (file == (const FILE *) NULL)
567 policy_info=GetPolicyInfoList("*",&number_policies,exception);
568 if (policy_info == (const PolicyInfo **) NULL)
570 path=(const char *) NULL;
571 for (i=0; i < (ssize_t) number_policies; i++)
573 if (policy_info[i]->stealth != MagickFalse)
575 if (((path == (const char *) NULL) ||
576 (LocaleCompare(path,policy_info[i]->path) != 0)) &&
577 (policy_info[i]->path != (char *) NULL))
578 (void) FormatLocaleFile(file,"\nPath: %s\n",policy_info[i]->path);
579 path=policy_info[i]->path;
580 domain=CommandOptionToMnemonic(MagickPolicyDomainOptions,
581 policy_info[i]->domain);
582 (void) FormatLocaleFile(file," Policy: %s\n",domain);
583 if ((policy_info[i]->domain == ResourcePolicyDomain) ||
584 (policy_info[i]->domain == SystemPolicyDomain))
586 if (policy_info[i]->name != (char *) NULL)
587 (void) FormatLocaleFile(file," name: %s\n",policy_info[i]->name);
588 if (policy_info[i]->value != (char *) NULL)
589 (void) FormatLocaleFile(file," value: %s\n",policy_info[i]->value);
593 (void) FormatLocaleFile(file," rights: ");
594 if (policy_info[i]->rights == NoPolicyRights)
595 (void) FormatLocaleFile(file,"None ");
596 if ((policy_info[i]->rights & ReadPolicyRights) != 0)
597 (void) FormatLocaleFile(file,"Read ");
598 if ((policy_info[i]->rights & WritePolicyRights) != 0)
599 (void) FormatLocaleFile(file,"Write ");
600 if ((policy_info[i]->rights & ExecutePolicyRights) != 0)
601 (void) FormatLocaleFile(file,"Execute ");
602 (void) FormatLocaleFile(file,"\n");
603 if (policy_info[i]->pattern != (char *) NULL)
604 (void) FormatLocaleFile(file," pattern: %s\n",
605 policy_info[i]->pattern);
608 policy_info=(const PolicyInfo **) RelinquishMagickMemory((void *)
615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
619 + L o a d P o l i c y L i s t %
623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
625 % LoadPolicyList() loads the policy configuration file which provides a mapping
626 % between policy attributes and a policy domain.
628 % The format of the LoadPolicyList method is:
630 % MagickBooleanType LoadPolicyList(const char *xml,const char *filename,
631 % const size_t depth,ExceptionInfo *exception)
633 % A description of each parameter follows:
635 % o xml: The policy list in XML format.
637 % o filename: The policy list filename.
639 % o depth: depth of <include /> statements.
641 % o exception: return any errors or warnings in this structure.
644 static MagickBooleanType LoadPolicyList(const char *xml,const char *filename,
645 const size_t depth,ExceptionInfo *exception)
648 keyword[MaxTextExtent],
661 Load the policy map file.
663 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
664 "Loading policy file \"%s\" ...",filename);
665 if (xml == (char *) NULL)
667 if (policy_list == (LinkedListInfo *) NULL)
669 policy_list=NewLinkedList(0);
670 if (policy_list == (LinkedListInfo *) NULL)
672 ThrowFileException(exception,ResourceLimitError,
673 "MemoryAllocationFailed",filename);
678 policy_info=(PolicyInfo *) NULL;
679 token=AcquireString(xml);
680 for (q=(const char *) xml; *q != '\0'; )
685 GetMagickToken(q,&q,token);
688 (void) CopyMagickString(keyword,token,MaxTextExtent);
689 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
694 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
695 GetMagickToken(q,&q,token);
698 if (LocaleNCompare(keyword,"<!--",4) == 0)
703 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
704 GetMagickToken(q,&q,token);
707 if (LocaleCompare(keyword,"<include") == 0)
712 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
714 (void) CopyMagickString(keyword,token,MaxTextExtent);
715 GetMagickToken(q,&q,token);
718 GetMagickToken(q,&q,token);
719 if (LocaleCompare(keyword,"file") == 0)
722 (void) ThrowMagickException(exception,GetMagickModule(),
723 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
730 GetPathComponent(filename,HeadPath,path);
732 (void) ConcatenateMagickString(path,DirectorySeparator,
734 if (*token == *DirectorySeparator)
735 (void) CopyMagickString(path,token,MaxTextExtent);
737 (void) ConcatenateMagickString(path,token,MaxTextExtent);
738 xml=FileToString(path,~0,exception);
739 if (xml != (char *) NULL)
741 status=LoadPolicyList(xml,path,depth+1,exception);
742 xml=(char *) RelinquishMagickMemory(xml);
749 if (LocaleCompare(keyword,"<policy") == 0)
754 policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
755 if (policy_info == (PolicyInfo *) NULL)
756 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
757 (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info));
758 policy_info->path=ConstantString(filename);
759 policy_info->exempt=MagickFalse;
760 policy_info->signature=MagickSignature;
763 if (policy_info == (PolicyInfo *) NULL)
765 if (LocaleCompare(keyword,"/>") == 0)
767 status=AppendValueToLinkedList(policy_list,policy_info);
768 if (status == MagickFalse)
769 (void) ThrowMagickException(exception,GetMagickModule(),
770 ResourceLimitError,"MemoryAllocationFailed","`%s'",
772 policy_info=(PolicyInfo *) NULL;
774 GetMagickToken(q,(const char **) NULL,token);
777 GetMagickToken(q,&q,token);
778 GetMagickToken(q,&q,token);
784 if (LocaleCompare((char *) keyword,"domain") == 0)
786 policy_info->domain=(PolicyDomain) ParseCommandOption(
787 MagickPolicyDomainOptions,MagickTrue,token);
795 if (LocaleCompare((char *) keyword,"name") == 0)
797 policy_info->name=ConstantString(token);
805 if (LocaleCompare((char *) keyword,"pattern") == 0)
807 policy_info->pattern=ConstantString(token);
815 if (LocaleCompare((char *) keyword,"rights") == 0)
817 policy_info->rights=(PolicyRights) ParseCommandOption(
818 MagickPolicyRightsOptions,MagickTrue,token);
826 if (LocaleCompare((char *) keyword,"stealth") == 0)
828 policy_info->stealth=IsMagickTrue(token);
836 if (LocaleCompare((char *) keyword,"value") == 0)
838 policy_info->value=ConstantString(token);
847 token=(char *) RelinquishMagickMemory(token);
852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
856 % L o a d P o l i c y L i s t s %
860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
862 % LoadPolicyList() loads one or more policy configuration file which provides a
863 % mapping between policy attributes and a policy name.
865 % The format of the LoadPolicyLists method is:
867 % MagickBooleanType LoadPolicyLists(const char *filename,
868 % ExceptionInfo *exception)
870 % A description of each parameter follows:
872 % o filename: the font file name.
874 % o exception: return any errors or warnings in this structure.
877 static MagickBooleanType LoadPolicyLists(const char *filename,
878 ExceptionInfo *exception)
893 Load built-in policy map.
896 if (policy_list == (LinkedListInfo *) NULL)
898 policy_list=NewLinkedList(0);
899 if (policy_list == (LinkedListInfo *) NULL)
901 ThrowFileException(exception,ResourceLimitError,
902 "MemoryAllocationFailed",filename);
906 for (i=0; i < (ssize_t) (sizeof(PolicyMap)/sizeof(*PolicyMap)); i++)
911 register const PolicyMapInfo
915 policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
916 if (policy_info == (PolicyInfo *) NULL)
918 (void) ThrowMagickException(exception,GetMagickModule(),
919 ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name);
922 (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info));
923 policy_info->path=(char *) "[built-in]";
924 policy_info->domain=p->domain;
925 policy_info->rights=p->rights;
926 policy_info->name=(char *) p->name;
927 policy_info->pattern=(char *) p->pattern;
928 policy_info->value=(char *) p->value;
929 policy_info->exempt=MagickTrue;
930 policy_info->signature=MagickSignature;
931 status=AppendValueToLinkedList(policy_list,policy_info);
932 if (status == MagickFalse)
933 (void) ThrowMagickException(exception,GetMagickModule(),
934 ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name);
937 Load external policy map.
939 options=GetConfigureOptions(filename,exception);
940 option=(const StringInfo *) GetNextValueInLinkedList(options);
941 while (option != (const StringInfo *) NULL)
943 status|=LoadPolicyList((const char *) GetStringInfoDatum(option),
944 GetStringInfoPath(option),0,exception);
945 option=(const StringInfo *) GetNextValueInLinkedList(options);
947 options=DestroyConfigureOptions(options);
948 return(status != 0 ? MagickTrue : MagickFalse);
952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
956 + P o l i c y C o m p o n e n t G e n e s i s %
960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
962 % PolicyComponentGenesis() instantiates the policy component.
964 % The format of the PolicyComponentGenesis method is:
966 % MagickBooleanType PolicyComponentGenesis(void)
969 MagickPrivate MagickBooleanType PolicyComponentGenesis(void)
971 AcquireSemaphoreInfo(&policy_semaphore);
976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
980 + P o l i c y C o m p o n e n t T e r m i n u s %
984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
986 % PolicyComponentTerminus() destroys the policy component.
988 % The format of the PolicyComponentTerminus method is:
990 % PolicyComponentTerminus(void)
994 static void *DestroyPolicyElement(void *policy_info)
999 p=(PolicyInfo *) policy_info;
1000 if (p->exempt == MagickFalse)
1002 if (p->value != (char *) NULL)
1003 p->value=DestroyString(p->value);
1004 if (p->pattern != (char *) NULL)
1005 p->pattern=DestroyString(p->pattern);
1006 if (p->name != (char *) NULL)
1007 p->name=DestroyString(p->name);
1008 if (p->path != (char *) NULL)
1009 p->path=DestroyString(p->path);
1011 p=(PolicyInfo *) RelinquishMagickMemory(p);
1012 return((void *) NULL);
1015 MagickPrivate void PolicyComponentTerminus(void)
1017 if (policy_semaphore == (SemaphoreInfo *) NULL)
1018 AcquireSemaphoreInfo(&policy_semaphore);
1019 LockSemaphoreInfo(policy_semaphore);
1020 if (policy_list != (LinkedListInfo *) NULL)
1021 policy_list=DestroyLinkedList(policy_list,DestroyPolicyElement);
1022 instantiate_policy=MagickFalse;
1023 UnlockSemaphoreInfo(policy_semaphore);
1024 DestroySemaphoreInfo(&policy_semaphore);