2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 % PPPP OOO L IIIII CCCC Y Y %
9 % P OOO LLLLL IIIII CCCC Y %
12 % MagickCore Policy Methods %
19 % Copyright 1999-2014 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;
129 Forward declarations.
131 static MagickBooleanType
132 IsPolicyListInstantiated(ExceptionInfo *),
133 LoadPolicyLists(const char *,ExceptionInfo *);
136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
140 + G e t P o l i c y I n f o %
144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 % GetPolicyInfo() searches the policy list for the specified name and if found
147 % returns attributes for that policy.
149 % The format of the GetPolicyInfo method is:
151 % PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
153 % A description of each parameter follows:
155 % o name: the policy name.
157 % o exception: return any errors or warnings in this structure.
160 static PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception)
163 policyname[MaxTextExtent];
171 assert(exception != (ExceptionInfo *) NULL);
172 if (IsPolicyListInstantiated(exception) == MagickFalse)
173 return((PolicyInfo *) NULL);
174 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
175 return((PolicyInfo *) GetValueFromLinkedList(policy_list,0));
177 Strip names of whitespace.
179 (void) CopyMagickString(policyname,name,MaxTextExtent);
180 for (q=policyname; *q != '\0'; q++)
182 if (isspace((int) ((unsigned char) *q)) == 0)
184 (void) CopyMagickString(q,q+1,MaxTextExtent);
188 Search for policy tag.
190 LockSemaphoreInfo(policy_semaphore);
191 ResetLinkedListIterator(policy_list);
192 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
193 while (p != (PolicyInfo *) NULL)
195 if (LocaleCompare(policyname,p->name) == 0)
197 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
199 if (p != (PolicyInfo *) NULL)
200 (void) InsertValueInLinkedList(policy_list,0,
201 RemoveElementByValueFromLinkedList(policy_list,p));
202 UnlockSemaphoreInfo(policy_semaphore);
207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
211 % G e t P o l i c y I n f o L i s t %
215 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
217 % GetPolicyInfoList() returns any policies that match the specified pattern.
219 % The format of the GetPolicyInfoList function is:
221 % const PolicyInfo **GetPolicyInfoList(const char *pattern,
222 % size_t *number_policies,ExceptionInfo *exception)
224 % A description of each parameter follows:
226 % o pattern: Specifies a pointer to a text string containing a pattern.
228 % o number_policies: returns the number of policies in the list.
230 % o exception: return any errors or warnings in this structure.
233 MagickExport const PolicyInfo **GetPolicyInfoList(const char *pattern,
234 size_t *number_policies,ExceptionInfo *exception)
239 register const PolicyInfo
246 Allocate policy list.
248 assert(pattern != (char *) NULL);
249 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
250 assert(number_policies != (size_t *) NULL);
252 p=GetPolicyInfo("*",exception);
253 if (p == (const PolicyInfo *) NULL)
254 return((const PolicyInfo **) NULL);
255 policies=(const PolicyInfo **) AcquireQuantumMemory((size_t)
256 GetNumberOfElementsInLinkedList(policy_list)+1UL,sizeof(*policies));
257 if (policies == (const PolicyInfo **) NULL)
258 return((const PolicyInfo **) NULL);
260 Generate policy list.
262 LockSemaphoreInfo(policy_semaphore);
263 ResetLinkedListIterator(policy_list);
264 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
265 for (i=0; p != (const PolicyInfo *) NULL; )
267 if ((p->stealth == MagickFalse) &&
268 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
270 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
272 UnlockSemaphoreInfo(policy_semaphore);
273 policies[i]=(PolicyInfo *) NULL;
274 *number_policies=(size_t) i;
279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283 % G e t P o l i c y L i s t %
287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
289 % GetPolicyList() returns any policies that match the specified pattern.
291 % The format of the GetPolicyList function is:
293 % char **GetPolicyList(const char *pattern,size_t *number_policies,
294 % ExceptionInfo *exception)
296 % A description of each parameter follows:
298 % o pattern: a pointer to a text string containing a pattern.
300 % o number_policies: returns the number of policies in the list.
302 % o exception: return any errors or warnings in this structure.
305 MagickExport char **GetPolicyList(const char *pattern,
306 size_t *number_policies,ExceptionInfo *exception)
311 register const PolicyInfo
318 Allocate policy list.
320 assert(pattern != (char *) NULL);
321 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
322 assert(number_policies != (size_t *) NULL);
324 p=GetPolicyInfo("*",exception);
325 if (p == (const PolicyInfo *) NULL)
326 return((char **) NULL);
327 policies=(char **) AcquireQuantumMemory((size_t)
328 GetNumberOfElementsInLinkedList(policy_list)+1UL,sizeof(*policies));
329 if (policies == (char **) NULL)
330 return((char **) NULL);
332 Generate policy list.
334 LockSemaphoreInfo(policy_semaphore);
335 ResetLinkedListIterator(policy_list);
336 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
337 for (i=0; p != (const PolicyInfo *) NULL; )
339 if ((p->stealth == MagickFalse) &&
340 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
341 policies[i++]=ConstantString(p->name);
342 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
344 UnlockSemaphoreInfo(policy_semaphore);
345 policies[i]=(char *) NULL;
346 *number_policies=(size_t) i;
351 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
355 % G e t P o l i c y V a l u e %
359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
361 % GetPolicyValue() returns the value associated with the named policy.
363 % The format of the GetPolicyValue method is:
365 % char *GetPolicyValue(const char *name)
367 % A description of each parameter follows:
369 % o policy_info: The policy info.
372 MagickExport char *GetPolicyValue(const char *name)
383 assert(name != (const char *) NULL);
384 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
385 exception=AcquireExceptionInfo();
386 policy_info=GetPolicyInfo(name,exception);
387 exception=DestroyExceptionInfo(exception);
388 if (policy_info == (PolicyInfo *) NULL)
389 return((char *) NULL);
390 value=policy_info->value;
391 if ((value == (const char *) NULL) || (*value == '\0'))
392 return((char *) NULL);
393 return(ConstantString(value));
397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401 + I s P o l i c y L i s t I n s t a n t i a t e d %
405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
407 % IsPolicyListInstantiated() determines if the policy list is instantiated.
408 % If not, it instantiates the list and returns it.
410 % The format of the IsPolicyInstantiated method is:
412 % MagickBooleanType IsPolicyListInstantiated(ExceptionInfo *exception)
414 % A description of each parameter follows.
416 % o exception: return any errors or warnings in this structure.
419 static MagickBooleanType IsPolicyListInstantiated(ExceptionInfo *exception)
421 if (policy_semaphore == (SemaphoreInfo *) NULL)
422 ActivateSemaphoreInfo(&policy_semaphore);
423 LockSemaphoreInfo(policy_semaphore);
424 if (policy_list == (LinkedListInfo *) NULL)
425 (void) LoadPolicyLists(PolicyFilename,exception);
426 UnlockSemaphoreInfo(policy_semaphore);
427 return(policy_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
435 % I s R i g h t s A u t h o r i z e d %
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
441 % IsRightsAuthorized() returns MagickTrue if the policy authorizes the
442 % requested rights for the specified domain.
444 % The format of the IsRightsAuthorized method is:
446 % MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
447 % const PolicyRights rights,const char *pattern)
449 % A description of each parameter follows:
451 % o domain: the policy domain.
453 % o rights: the policy rights.
455 % o pattern: the coder, delegate, filter, or path pattern.
458 MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
459 const PolicyRights rights,const char *pattern)
473 (void) LogMagickEvent(PolicyEvent,GetMagickModule(),
474 "Domain: %s; rights=%s; pattern=\"%s\" ...",
475 CommandOptionToMnemonic(MagickPolicyDomainOptions,domain),
476 CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),pattern);
477 exception=AcquireExceptionInfo();
478 policy_info=GetPolicyInfo("*",exception);
479 exception=DestroyExceptionInfo(exception);
480 if (policy_info == (PolicyInfo *) NULL)
482 authorized=MagickTrue;
483 LockSemaphoreInfo(policy_semaphore);
484 ResetLinkedListIterator(policy_list);
485 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
486 while ((p != (PolicyInfo *) NULL) && (authorized != MagickFalse))
488 if ((p->domain == domain) &&
489 (GlobExpression(pattern,p->pattern,MagickFalse) != MagickFalse))
491 if (((rights & ReadPolicyRights) != 0) &&
492 ((p->rights & ReadPolicyRights) == 0))
493 authorized=MagickFalse;
494 if (((rights & WritePolicyRights) != 0) &&
495 ((p->rights & WritePolicyRights) == 0))
496 authorized=MagickFalse;
497 if (((rights & ExecutePolicyRights) != 0) &&
498 ((p->rights & ExecutePolicyRights) == 0))
499 authorized=MagickFalse;
501 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
503 UnlockSemaphoreInfo(policy_semaphore);
508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
512 % L i s t P o l i c y I n f o %
516 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
518 % ListPolicyInfo() lists policies to the specified file.
520 % The format of the ListPolicyInfo method is:
522 % MagickBooleanType ListPolicyInfo(FILE *file,ExceptionInfo *exception)
524 % A description of each parameter follows.
526 % o file: List policy names to this file handle.
528 % o exception: return any errors or warnings in this structure.
531 MagickExport MagickBooleanType ListPolicyInfo(FILE *file,
532 ExceptionInfo *exception)
548 List name and attributes of each policy in the list.
550 if (file == (const FILE *) NULL)
552 policy_info=GetPolicyInfoList("*",&number_policies,exception);
553 if (policy_info == (const PolicyInfo **) NULL)
555 path=(const char *) NULL;
556 for (i=0; i < (ssize_t) number_policies; i++)
558 if (policy_info[i]->stealth != MagickFalse)
560 if (((path == (const char *) NULL) ||
561 (LocaleCompare(path,policy_info[i]->path) != 0)) &&
562 (policy_info[i]->path != (char *) NULL))
563 (void) FormatLocaleFile(file,"\nPath: %s\n",policy_info[i]->path);
564 path=policy_info[i]->path;
565 domain=CommandOptionToMnemonic(MagickPolicyDomainOptions,
566 policy_info[i]->domain);
567 (void) FormatLocaleFile(file," Policy: %s\n",domain);
568 if ((policy_info[i]->domain == ResourcePolicyDomain) ||
569 (policy_info[i]->domain == SystemPolicyDomain))
571 if (policy_info[i]->name != (char *) NULL)
572 (void) FormatLocaleFile(file," name: %s\n",policy_info[i]->name);
573 if (policy_info[i]->value != (char *) NULL)
574 (void) FormatLocaleFile(file," value: %s\n",policy_info[i]->value);
578 (void) FormatLocaleFile(file," rights: ");
579 if (policy_info[i]->rights == NoPolicyRights)
580 (void) FormatLocaleFile(file,"None ");
581 if ((policy_info[i]->rights & ReadPolicyRights) != 0)
582 (void) FormatLocaleFile(file,"Read ");
583 if ((policy_info[i]->rights & WritePolicyRights) != 0)
584 (void) FormatLocaleFile(file,"Write ");
585 if ((policy_info[i]->rights & ExecutePolicyRights) != 0)
586 (void) FormatLocaleFile(file,"Execute ");
587 (void) FormatLocaleFile(file,"\n");
588 if (policy_info[i]->pattern != (char *) NULL)
589 (void) FormatLocaleFile(file," pattern: %s\n",
590 policy_info[i]->pattern);
593 policy_info=(const PolicyInfo **) RelinquishMagickMemory((void *)
600 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604 + L o a d P o l i c y L i s t %
608 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
610 % LoadPolicyList() loads the policy configuration file which provides a mapping
611 % between policy attributes and a policy domain.
613 % The format of the LoadPolicyList method is:
615 % MagickBooleanType LoadPolicyList(const char *xml,const char *filename,
616 % const size_t depth,ExceptionInfo *exception)
618 % A description of each parameter follows:
620 % o xml: The policy list in XML format.
622 % o filename: The policy list filename.
624 % o depth: depth of <include /> statements.
626 % o exception: return any errors or warnings in this structure.
629 static MagickBooleanType LoadPolicyList(const char *xml,const char *filename,
630 const size_t depth,ExceptionInfo *exception)
633 keyword[MaxTextExtent],
646 Load the policy map file.
648 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
649 "Loading policy file \"%s\" ...",filename);
650 if (xml == (char *) NULL)
652 if (policy_list == (LinkedListInfo *) NULL)
654 policy_list=NewLinkedList(0);
655 if (policy_list == (LinkedListInfo *) NULL)
657 ThrowFileException(exception,ResourceLimitError,
658 "MemoryAllocationFailed",filename);
663 policy_info=(PolicyInfo *) NULL;
664 token=AcquireString(xml);
665 for (q=(const char *) xml; *q != '\0'; )
670 GetMagickToken(q,&q,token);
673 (void) CopyMagickString(keyword,token,MaxTextExtent);
674 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
679 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
680 GetMagickToken(q,&q,token);
683 if (LocaleNCompare(keyword,"<!--",4) == 0)
688 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
689 GetMagickToken(q,&q,token);
692 if (LocaleCompare(keyword,"<include") == 0)
697 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
699 (void) CopyMagickString(keyword,token,MaxTextExtent);
700 GetMagickToken(q,&q,token);
703 GetMagickToken(q,&q,token);
704 if (LocaleCompare(keyword,"file") == 0)
707 (void) ThrowMagickException(exception,GetMagickModule(),
708 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
715 GetPathComponent(filename,HeadPath,path);
717 (void) ConcatenateMagickString(path,DirectorySeparator,
719 if (*token == *DirectorySeparator)
720 (void) CopyMagickString(path,token,MaxTextExtent);
722 (void) ConcatenateMagickString(path,token,MaxTextExtent);
723 xml=FileToString(path,~0UL,exception);
724 if (xml != (char *) NULL)
726 status=LoadPolicyList(xml,path,depth+1,exception);
727 xml=(char *) RelinquishMagickMemory(xml);
734 if (LocaleCompare(keyword,"<policy") == 0)
739 policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
740 if (policy_info == (PolicyInfo *) NULL)
741 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
742 (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info));
743 policy_info->path=ConstantString(filename);
744 policy_info->exempt=MagickFalse;
745 policy_info->signature=MagickSignature;
748 if (policy_info == (PolicyInfo *) NULL)
750 if (LocaleCompare(keyword,"/>") == 0)
752 status=AppendValueToLinkedList(policy_list,policy_info);
753 if (status == MagickFalse)
754 (void) ThrowMagickException(exception,GetMagickModule(),
755 ResourceLimitError,"MemoryAllocationFailed","`%s'",
757 policy_info=(PolicyInfo *) NULL;
760 GetMagickToken(q,(const char **) NULL,token);
763 GetMagickToken(q,&q,token);
764 GetMagickToken(q,&q,token);
770 if (LocaleCompare((char *) keyword,"domain") == 0)
772 policy_info->domain=(PolicyDomain) ParseCommandOption(
773 MagickPolicyDomainOptions,MagickTrue,token);
781 if (LocaleCompare((char *) keyword,"name") == 0)
783 policy_info->name=ConstantString(token);
791 if (LocaleCompare((char *) keyword,"pattern") == 0)
793 policy_info->pattern=ConstantString(token);
801 if (LocaleCompare((char *) keyword,"rights") == 0)
803 policy_info->rights=(PolicyRights) ParseCommandOption(
804 MagickPolicyRightsOptions,MagickTrue,token);
812 if (LocaleCompare((char *) keyword,"stealth") == 0)
814 policy_info->stealth=IsStringTrue(token);
822 if (LocaleCompare((char *) keyword,"value") == 0)
824 policy_info->value=ConstantString(token);
833 token=(char *) RelinquishMagickMemory(token);
838 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
842 % L o a d P o l i c y L i s t s %
846 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
848 % LoadPolicyList() loads one or more policy configuration file which provides a
849 % mapping between policy attributes and a policy name.
851 % The format of the LoadPolicyLists method is:
853 % MagickBooleanType LoadPolicyLists(const char *filename,
854 % ExceptionInfo *exception)
856 % A description of each parameter follows:
858 % o filename: the font file name.
860 % o exception: return any errors or warnings in this structure.
863 static MagickBooleanType LoadPolicyLists(const char *filename,
864 ExceptionInfo *exception)
879 Load external policy map.
881 if (policy_list == (LinkedListInfo *) NULL)
883 policy_list=NewLinkedList(0);
884 if (policy_list == (LinkedListInfo *) NULL)
886 ThrowFileException(exception,ResourceLimitError,
887 "MemoryAllocationFailed",filename);
892 options=GetConfigureOptions(filename,exception);
893 option=(const StringInfo *) GetNextValueInLinkedList(options);
894 while (option != (const StringInfo *) NULL)
896 status&=LoadPolicyList((const char *) GetStringInfoDatum(option),
897 GetStringInfoPath(option),0,exception);
898 option=(const StringInfo *) GetNextValueInLinkedList(options);
900 options=DestroyConfigureOptions(options);
902 Load built-in policy map.
904 for (i=0; i < (ssize_t) (sizeof(PolicyMap)/sizeof(*PolicyMap)); i++)
909 register const PolicyMapInfo
913 policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
914 if (policy_info == (PolicyInfo *) NULL)
916 (void) ThrowMagickException(exception,GetMagickModule(),
917 ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
920 (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info));
921 policy_info->path=(char *) "[built-in]";
922 policy_info->domain=p->domain;
923 policy_info->rights=p->rights;
924 policy_info->name=(char *) p->name;
925 policy_info->pattern=(char *) p->pattern;
926 policy_info->value=(char *) p->value;
927 policy_info->exempt=MagickTrue;
928 policy_info->signature=MagickSignature;
929 status&=AppendValueToLinkedList(policy_list,policy_info);
930 if (status == MagickFalse)
931 (void) ThrowMagickException(exception,GetMagickModule(),
932 ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name);
934 return(status != 0 ? MagickTrue : MagickFalse);
938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
942 + P o l i c y C o m p o n e n t G e n e s i s %
946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
948 % PolicyComponentGenesis() instantiates the policy component.
950 % The format of the PolicyComponentGenesis method is:
952 % MagickBooleanType PolicyComponentGenesis(void)
955 MagickPrivate MagickBooleanType PolicyComponentGenesis(void)
957 policy_semaphore=AcquireSemaphoreInfo();
962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
966 + P o l i c y C o m p o n e n t T e r m i n u s %
970 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
972 % PolicyComponentTerminus() destroys the policy component.
974 % The format of the PolicyComponentTerminus method is:
976 % PolicyComponentTerminus(void)
980 static void *DestroyPolicyElement(void *policy_info)
985 p=(PolicyInfo *) policy_info;
986 if (p->exempt == MagickFalse)
988 if (p->value != (char *) NULL)
989 p->value=DestroyString(p->value);
990 if (p->pattern != (char *) NULL)
991 p->pattern=DestroyString(p->pattern);
992 if (p->name != (char *) NULL)
993 p->name=DestroyString(p->name);
994 if (p->path != (char *) NULL)
995 p->path=DestroyString(p->path);
997 p=(PolicyInfo *) RelinquishMagickMemory(p);
998 return((void *) NULL);
1001 MagickPrivate void PolicyComponentTerminus(void)
1003 if (policy_semaphore == (SemaphoreInfo *) NULL)
1004 ActivateSemaphoreInfo(&policy_semaphore);
1005 LockSemaphoreInfo(policy_semaphore);
1006 if (policy_list != (LinkedListInfo *) NULL)
1007 policy_list=DestroyLinkedList(policy_list,DestroyPolicyElement);
1008 UnlockSemaphoreInfo(policy_semaphore);
1009 RelinquishSemaphoreInfo(&policy_semaphore);