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/exception.h"
47 #include "MagickCore/exception-private.h"
48 #include "MagickCore/memory_.h"
49 #include "MagickCore/monitor.h"
50 #include "MagickCore/monitor-private.h"
51 #include "MagickCore/option.h"
52 #include "MagickCore/policy.h"
53 #include "MagickCore/semaphore.h"
54 #include "MagickCore/string_.h"
55 #include "MagickCore/token.h"
56 #include "MagickCore/utility.h"
57 #include "MagickCore/xml-tree.h"
62 #define PolicyFilename "policy.xml"
95 typedef struct _PolicyMapInfo
112 static const PolicyMapInfo
115 { UndefinedPolicyDomain, UndefinedPolicyRights, (const char *) NULL,
116 (const char *) NULL, (const char *) NULL }
119 static LinkedListInfo
120 *policy_list = (LinkedListInfo *) NULL;
123 *policy_semaphore = (SemaphoreInfo *) NULL;
125 static volatile MagickBooleanType
126 instantiate_policy = MagickFalse;
129 Forward declarations.
131 static MagickBooleanType
132 InitializePolicyList(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 ((policy_list == (LinkedListInfo *) NULL) ||
173 (instantiate_policy == MagickFalse))
174 if (InitializePolicyList(exception) == MagickFalse)
175 return((PolicyInfo *) NULL);
176 if ((policy_list == (LinkedListInfo *) NULL) ||
177 (IsLinkedListEmpty(policy_list) != MagickFalse))
178 return((PolicyInfo *) NULL);
179 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
180 return((PolicyInfo *) GetValueFromLinkedList(policy_list,0));
182 Strip names of whitespace.
184 (void) CopyMagickString(policyname,name,MaxTextExtent);
185 for (q=policyname; *q != '\0'; q++)
187 if (isspace((int) ((unsigned char) *q)) == 0)
189 (void) CopyMagickString(q,q+1,MaxTextExtent);
193 Search for policy tag.
195 LockSemaphoreInfo(policy_semaphore);
196 ResetLinkedListIterator(policy_list);
197 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
198 while (p != (PolicyInfo *) NULL)
200 if (LocaleCompare(policyname,p->name) == 0)
202 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
204 if (p != (PolicyInfo *) NULL)
205 (void) InsertValueInLinkedList(policy_list,0,
206 RemoveElementByValueFromLinkedList(policy_list,p));
207 UnlockSemaphoreInfo(policy_semaphore);
212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
216 % G e t P o l i c y I n f o L i s t %
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 % GetPolicyInfoList() returns any policies that match the specified pattern.
224 % The format of the GetPolicyInfoList function is:
226 % const PolicyInfo **GetPolicyInfoList(const char *pattern,
227 % size_t *number_policies,ExceptionInfo *exception)
229 % A description of each parameter follows:
231 % o pattern: Specifies a pointer to a text string containing a pattern.
233 % o number_policies: returns the number of policies in the list.
235 % o exception: return any errors or warnings in this structure.
238 MagickExport const PolicyInfo **GetPolicyInfoList(const char *pattern,
239 size_t *number_policies,ExceptionInfo *exception)
244 register const PolicyInfo
251 Allocate policy list.
253 assert(pattern != (char *) NULL);
254 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
255 assert(number_policies != (size_t *) NULL);
257 p=GetPolicyInfo("*",exception);
258 if (p == (const PolicyInfo *) NULL)
259 return((const PolicyInfo **) NULL);
260 policies=(const PolicyInfo **) AcquireQuantumMemory((size_t)
261 GetNumberOfElementsInLinkedList(policy_list)+1UL,sizeof(*policies));
262 if (policies == (const PolicyInfo **) NULL)
263 return((const PolicyInfo **) NULL);
265 Generate policy list.
267 LockSemaphoreInfo(policy_semaphore);
268 ResetLinkedListIterator(policy_list);
269 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
270 for (i=0; p != (const PolicyInfo *) NULL; )
272 if ((p->stealth == MagickFalse) &&
273 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
275 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
277 UnlockSemaphoreInfo(policy_semaphore);
278 policies[i]=(PolicyInfo *) NULL;
279 *number_policies=(size_t) i;
284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
288 % G e t P o l i c y L i s t %
292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294 % GetPolicyList() returns any policies that match the specified pattern.
296 % The format of the GetPolicyList function is:
298 % char **GetPolicyList(const char *pattern,size_t *number_policies,
299 % ExceptionInfo *exception)
301 % A description of each parameter follows:
303 % o pattern: a pointer to a text string containing a pattern.
305 % o number_policies: returns the number of policies in the list.
307 % o exception: return any errors or warnings in this structure.
310 MagickExport char **GetPolicyList(const char *pattern,
311 size_t *number_policies,ExceptionInfo *exception)
316 register const PolicyInfo
323 Allocate policy list.
325 assert(pattern != (char *) NULL);
326 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
327 assert(number_policies != (size_t *) NULL);
329 p=GetPolicyInfo("*",exception);
330 if (p == (const PolicyInfo *) NULL)
331 return((char **) NULL);
332 policies=(char **) AcquireQuantumMemory((size_t)
333 GetNumberOfElementsInLinkedList(policy_list)+1UL,sizeof(*policies));
334 if (policies == (char **) NULL)
335 return((char **) NULL);
337 Generate policy list.
339 LockSemaphoreInfo(policy_semaphore);
340 ResetLinkedListIterator(policy_list);
341 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
342 for (i=0; p != (const PolicyInfo *) NULL; )
344 if ((p->stealth == MagickFalse) &&
345 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
346 policies[i++]=ConstantString(p->name);
347 p=(const PolicyInfo *) GetNextValueInLinkedList(policy_list);
349 UnlockSemaphoreInfo(policy_semaphore);
350 policies[i]=(char *) NULL;
351 *number_policies=(size_t) i;
356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
360 % G e t P o l i c y V a l u e %
364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
366 % GetPolicyValue() returns the value associated with the named policy.
368 % The format of the GetPolicyValue method is:
370 % char *GetPolicyValue(const char *name)
372 % A description of each parameter follows:
374 % o policy_info: The policy info.
377 MagickExport char *GetPolicyValue(const char *name)
388 assert(name != (const char *) NULL);
389 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
390 exception=AcquireExceptionInfo();
391 policy_info=GetPolicyInfo(name,exception);
392 exception=DestroyExceptionInfo(exception);
393 if (policy_info == (PolicyInfo *) NULL)
394 return((char *) NULL);
395 value=policy_info->value;
396 if ((value == (const char *) NULL) || (*value == '\0'))
397 return((char *) NULL);
398 return(ConstantString(value));
402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
406 + I n i t i a l i z e P o l i c y L i s t %
410 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
412 % InitializePolicyList() initializes the policy list.
414 % The format of the InitializePolicyList method is:
416 % MagickBooleanType InitializePolicyList(ExceptionInfo *exception)
418 % A description of each parameter follows.
420 % o exception: return any errors or warnings in this structure.
423 static MagickBooleanType InitializePolicyList(ExceptionInfo *exception)
425 if ((policy_list == (LinkedListInfo *) NULL) &&
426 (instantiate_policy == MagickFalse))
428 if (policy_semaphore == (SemaphoreInfo *) NULL)
429 AcquireSemaphoreInfo(&policy_semaphore);
430 LockSemaphoreInfo(policy_semaphore);
431 if ((policy_list == (LinkedListInfo *) NULL) &&
432 (instantiate_policy == MagickFalse))
434 (void) LoadPolicyLists(PolicyFilename,exception);
435 instantiate_policy=MagickTrue;
437 UnlockSemaphoreInfo(policy_semaphore);
439 return(policy_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
443 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
447 % I s R i g h t s A u t h o r i z e d %
451 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
453 % IsRightsAuthorized() returns MagickTrue if the policy authorizes the
454 % requested rights for the specified domain.
456 % The format of the IsRightsAuthorized method is:
458 % MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
459 % const PolicyRights rights,const char *pattern)
461 % A description of each parameter follows:
463 % o domain: the policy domain.
465 % o rights: the policy rights.
467 % o pattern: the coder, delegate, filter, or path pattern.
470 MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain,
471 const PolicyRights rights,const char *pattern)
485 (void) LogMagickEvent(PolicyEvent,GetMagickModule(),
486 "Domain: %s; rights=%s; pattern=\"%s\" ...",
487 CommandOptionToMnemonic(MagickPolicyDomainOptions,domain),
488 CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),pattern);
489 exception=AcquireExceptionInfo();
490 policy_info=GetPolicyInfo("*",exception);
491 exception=DestroyExceptionInfo(exception);
492 if (policy_info == (PolicyInfo *) NULL)
494 authorized=MagickTrue;
495 LockSemaphoreInfo(policy_semaphore);
496 ResetLinkedListIterator(policy_list);
497 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
498 while ((p != (PolicyInfo *) NULL) && (authorized != MagickFalse))
500 if ((p->domain == domain) &&
501 (GlobExpression(pattern,p->pattern,MagickFalse) != MagickFalse))
503 if (((rights & ReadPolicyRights) != 0) &&
504 ((p->rights & ReadPolicyRights) == 0))
505 authorized=MagickFalse;
506 if (((rights & WritePolicyRights) != 0) &&
507 ((p->rights & WritePolicyRights) == 0))
508 authorized=MagickFalse;
509 if (((rights & ExecutePolicyRights) != 0) &&
510 ((p->rights & ExecutePolicyRights) == 0))
511 authorized=MagickFalse;
513 p=(PolicyInfo *) GetNextValueInLinkedList(policy_list);
515 UnlockSemaphoreInfo(policy_semaphore);
520 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
524 % L i s t P o l i c y I n f o %
528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
530 % ListPolicyInfo() lists policies to the specified file.
532 % The format of the ListPolicyInfo method is:
534 % MagickBooleanType ListPolicyInfo(FILE *file,ExceptionInfo *exception)
536 % A description of each parameter follows.
538 % o file: List policy names to this file handle.
540 % o exception: return any errors or warnings in this structure.
543 MagickExport MagickBooleanType ListPolicyInfo(FILE *file,
544 ExceptionInfo *exception)
560 List name and attributes of each policy in the list.
562 if (file == (const FILE *) NULL)
564 policy_info=GetPolicyInfoList("*",&number_policies,exception);
565 if (policy_info == (const PolicyInfo **) NULL)
567 path=(const char *) NULL;
568 for (i=0; i < (ssize_t) number_policies; i++)
570 if (policy_info[i]->stealth != MagickFalse)
572 if (((path == (const char *) NULL) ||
573 (LocaleCompare(path,policy_info[i]->path) != 0)) &&
574 (policy_info[i]->path != (char *) NULL))
575 (void) FormatLocaleFile(file,"\nPath: %s\n",policy_info[i]->path);
576 path=policy_info[i]->path;
577 domain=CommandOptionToMnemonic(MagickPolicyDomainOptions,
578 policy_info[i]->domain);
579 (void) FormatLocaleFile(file," Policy: %s\n",domain);
580 if ((policy_info[i]->domain == ResourcePolicyDomain) ||
581 (policy_info[i]->domain == SystemPolicyDomain))
583 if (policy_info[i]->name != (char *) NULL)
584 (void) FormatLocaleFile(file," name: %s\n",policy_info[i]->name);
585 if (policy_info[i]->value != (char *) NULL)
586 (void) FormatLocaleFile(file," value: %s\n",policy_info[i]->value);
590 (void) FormatLocaleFile(file," rights: ");
591 if (policy_info[i]->rights == NoPolicyRights)
592 (void) FormatLocaleFile(file,"None ");
593 if ((policy_info[i]->rights & ReadPolicyRights) != 0)
594 (void) FormatLocaleFile(file,"Read ");
595 if ((policy_info[i]->rights & WritePolicyRights) != 0)
596 (void) FormatLocaleFile(file,"Write ");
597 if ((policy_info[i]->rights & ExecutePolicyRights) != 0)
598 (void) FormatLocaleFile(file,"Execute ");
599 (void) FormatLocaleFile(file,"\n");
600 if (policy_info[i]->pattern != (char *) NULL)
601 (void) FormatLocaleFile(file," pattern: %s\n",
602 policy_info[i]->pattern);
605 policy_info=(const PolicyInfo **) RelinquishMagickMemory((void *)
612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
616 + L o a d P o l i c y L i s t %
620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
622 % LoadPolicyList() loads the policy configuration file which provides a mapping
623 % between policy attributes and a policy domain.
625 % The format of the LoadPolicyList method is:
627 % MagickBooleanType LoadPolicyList(const char *xml,const char *filename,
628 % const size_t depth,ExceptionInfo *exception)
630 % A description of each parameter follows:
632 % o xml: The policy list in XML format.
634 % o filename: The policy list filename.
636 % o depth: depth of <include /> statements.
638 % o exception: return any errors or warnings in this structure.
641 static MagickBooleanType LoadPolicyList(const char *xml,const char *filename,
642 const size_t depth,ExceptionInfo *exception)
645 keyword[MaxTextExtent],
658 Load the policy map file.
660 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
661 "Loading policy file \"%s\" ...",filename);
662 if (xml == (char *) NULL)
664 if (policy_list == (LinkedListInfo *) NULL)
666 policy_list=NewLinkedList(0);
667 if (policy_list == (LinkedListInfo *) NULL)
669 ThrowFileException(exception,ResourceLimitError,
670 "MemoryAllocationFailed",filename);
675 policy_info=(PolicyInfo *) NULL;
676 token=AcquireString(xml);
677 for (q=(const char *) xml; *q != '\0'; )
682 GetMagickToken(q,&q,token);
685 (void) CopyMagickString(keyword,token,MaxTextExtent);
686 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
691 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
692 GetMagickToken(q,&q,token);
695 if (LocaleNCompare(keyword,"<!--",4) == 0)
700 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
701 GetMagickToken(q,&q,token);
704 if (LocaleCompare(keyword,"<include") == 0)
709 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
711 (void) CopyMagickString(keyword,token,MaxTextExtent);
712 GetMagickToken(q,&q,token);
715 GetMagickToken(q,&q,token);
716 if (LocaleCompare(keyword,"file") == 0)
719 (void) ThrowMagickException(exception,GetMagickModule(),
720 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
727 GetPathComponent(filename,HeadPath,path);
729 (void) ConcatenateMagickString(path,DirectorySeparator,
731 if (*token == *DirectorySeparator)
732 (void) CopyMagickString(path,token,MaxTextExtent);
734 (void) ConcatenateMagickString(path,token,MaxTextExtent);
735 xml=FileToString(path,~0,exception);
736 if (xml != (char *) NULL)
738 status=LoadPolicyList(xml,path,depth+1,exception);
739 xml=(char *) RelinquishMagickMemory(xml);
746 if (LocaleCompare(keyword,"<policy") == 0)
751 policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
752 if (policy_info == (PolicyInfo *) NULL)
753 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
754 (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info));
755 policy_info->path=ConstantString(filename);
756 policy_info->exempt=MagickFalse;
757 policy_info->signature=MagickSignature;
760 if (policy_info == (PolicyInfo *) NULL)
762 if (LocaleCompare(keyword,"/>") == 0)
764 status=AppendValueToLinkedList(policy_list,policy_info);
765 if (status == MagickFalse)
766 (void) ThrowMagickException(exception,GetMagickModule(),
767 ResourceLimitError,"MemoryAllocationFailed","`%s'",
769 policy_info=(PolicyInfo *) NULL;
771 GetMagickToken(q,(const char **) NULL,token);
774 GetMagickToken(q,&q,token);
775 GetMagickToken(q,&q,token);
781 if (LocaleCompare((char *) keyword,"domain") == 0)
783 policy_info->domain=(PolicyDomain) ParseCommandOption(
784 MagickPolicyDomainOptions,MagickTrue,token);
792 if (LocaleCompare((char *) keyword,"name") == 0)
794 policy_info->name=ConstantString(token);
802 if (LocaleCompare((char *) keyword,"pattern") == 0)
804 policy_info->pattern=ConstantString(token);
812 if (LocaleCompare((char *) keyword,"rights") == 0)
814 policy_info->rights=(PolicyRights) ParseCommandOption(
815 MagickPolicyRightsOptions,MagickTrue,token);
823 if (LocaleCompare((char *) keyword,"stealth") == 0)
825 policy_info->stealth=IsMagickTrue(token);
833 if (LocaleCompare((char *) keyword,"value") == 0)
835 policy_info->value=ConstantString(token);
844 token=(char *) RelinquishMagickMemory(token);
849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
853 % L o a d P o l i c y L i s t s %
857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
859 % LoadPolicyList() loads one or more policy configuration file which provides a
860 % mapping between policy attributes and a policy name.
862 % The format of the LoadPolicyLists method is:
864 % MagickBooleanType LoadPolicyLists(const char *filename,
865 % ExceptionInfo *exception)
867 % A description of each parameter follows:
869 % o filename: the font file name.
871 % o exception: return any errors or warnings in this structure.
874 static MagickBooleanType LoadPolicyLists(const char *filename,
875 ExceptionInfo *exception)
890 Load built-in policy map.
893 if (policy_list == (LinkedListInfo *) NULL)
895 policy_list=NewLinkedList(0);
896 if (policy_list == (LinkedListInfo *) NULL)
898 ThrowFileException(exception,ResourceLimitError,
899 "MemoryAllocationFailed",filename);
903 for (i=0; i < (ssize_t) (sizeof(PolicyMap)/sizeof(*PolicyMap)); i++)
908 register const PolicyMapInfo
912 policy_info=(PolicyInfo *) AcquireMagickMemory(sizeof(*policy_info));
913 if (policy_info == (PolicyInfo *) NULL)
915 (void) ThrowMagickException(exception,GetMagickModule(),
916 ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name);
919 (void) ResetMagickMemory(policy_info,0,sizeof(*policy_info));
920 policy_info->path=(char *) "[built-in]";
921 policy_info->domain=p->domain;
922 policy_info->rights=p->rights;
923 policy_info->name=(char *) p->name;
924 policy_info->pattern=(char *) p->pattern;
925 policy_info->value=(char *) p->value;
926 policy_info->exempt=MagickTrue;
927 policy_info->signature=MagickSignature;
928 status=AppendValueToLinkedList(policy_list,policy_info);
929 if (status == MagickFalse)
930 (void) ThrowMagickException(exception,GetMagickModule(),
931 ResourceLimitError,"MemoryAllocationFailed","`%s'",policy_info->name);
934 Load external policy map.
936 options=GetConfigureOptions(filename,exception);
937 option=(const StringInfo *) GetNextValueInLinkedList(options);
938 while (option != (const StringInfo *) NULL)
940 status|=LoadPolicyList((const char *) GetStringInfoDatum(option),
941 GetStringInfoPath(option),0,exception);
942 option=(const StringInfo *) GetNextValueInLinkedList(options);
944 options=DestroyConfigureOptions(options);
945 return(status != 0 ? MagickTrue : MagickFalse);
949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
953 + P o l i c y C o m p o n e n t G e n e s i s %
957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
959 % PolicyComponentGenesis() instantiates the policy component.
961 % The format of the PolicyComponentGenesis method is:
963 % MagickBooleanType PolicyComponentGenesis(void)
966 MagickExport MagickBooleanType PolicyComponentGenesis(void)
968 AcquireSemaphoreInfo(&policy_semaphore);
973 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
977 + P o l i c y C o m p o n e n t T e r m i n u s %
981 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983 % PolicyComponentTerminus() destroys the policy component.
985 % The format of the PolicyComponentTerminus method is:
987 % PolicyComponentTerminus(void)
991 static void *DestroyPolicyElement(void *policy_info)
996 p=(PolicyInfo *) policy_info;
997 if (p->exempt == MagickFalse)
999 if (p->value != (char *) NULL)
1000 p->value=DestroyString(p->value);
1001 if (p->pattern != (char *) NULL)
1002 p->pattern=DestroyString(p->pattern);
1003 if (p->name != (char *) NULL)
1004 p->name=DestroyString(p->name);
1005 if (p->path != (char *) NULL)
1006 p->path=DestroyString(p->path);
1008 p=(PolicyInfo *) RelinquishMagickMemory(p);
1009 return((void *) NULL);
1012 MagickExport void PolicyComponentTerminus(void)
1014 if (policy_semaphore == (SemaphoreInfo *) NULL)
1015 AcquireSemaphoreInfo(&policy_semaphore);
1016 LockSemaphoreInfo(policy_semaphore);
1017 if (policy_list != (LinkedListInfo *) NULL)
1018 policy_list=DestroyLinkedList(policy_list,DestroyPolicyElement);
1019 instantiate_policy=MagickFalse;
1020 UnlockSemaphoreInfo(policy_semaphore);
1021 DestroySemaphoreInfo(&policy_semaphore);