/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t L o c a l e O p t i o n s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetLocaleOptions() returns any Magick configuration messages associated % with the specified filename. % % The format of the GetLocaleOptions method is: % % LinkedListInfo *GetLocaleOptions(const char *filename, % ExceptionInfo *exception) % % A description of each parameter follows: % % o filename: the locale file tag. % % o exception: return any errors or warnings in this structure. % */ MagickExport LinkedListInfo *GetLocaleOptions(const char *filename, ExceptionInfo *exception) { char path[MaxTextExtent]; const char *element; LinkedListInfo *messages, *paths; StringInfo *xml; assert(filename != (const char *) NULL); (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); assert(exception != (ExceptionInfo *) NULL); (void) CopyMagickString(path,filename,MaxTextExtent); /* Load XML from configuration files to linked-list. */ messages=NewLinkedList(0); paths=GetConfigurePaths(filename,exception); if (paths != (LinkedListInfo *) NULL) { ResetLinkedListIterator(paths); element=(const char *) GetNextValueInLinkedList(paths); while (element != (const char *) NULL) { (void) FormatMagickString(path,MaxTextExtent,"%s%s",element,filename); (void) LogMagickEvent(LocaleEvent,GetMagickModule(), "Searching for locale file: \"%s\"",path); xml=ConfigureFileToStringInfo(path); if (xml != (StringInfo *) NULL) (void) AppendValueToLinkedList(messages,xml); element=(const char *) GetNextValueInLinkedList(paths); } paths=DestroyLinkedList(paths,RelinquishMagickMemory); } #if defined(MAGICKCORE_WINDOWS_SUPPORT) { char *blob; blob=(char *) NTResourceToBlob(filename); if (blob != (char *) NULL) { xml=StringToStringInfo(blob); (void) AppendValueToLinkedList(messages,xml); blob=DestroyString(blob); } } #endif ResetLinkedListIterator(messages); return(messages); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % C a t c h E x c e p t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % CatchException() returns if no exceptions is found otherwise it reports % the exception as a warning, error, or fatal depending on the severity. % % The format of the CatchException method is: % % CatchException(ExceptionInfo *exception) % % A description of each parameter follows: % % o exception: the exception info. % */ MagickExport void CatchException(ExceptionInfo *exception) { register const ExceptionInfo *p; assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); if (exception->exceptions == (void *) NULL) return; LockSemaphoreInfo(exception->semaphore); ResetLinkedListIterator((LinkedListInfo *) exception->exceptions); p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *) exception->exceptions); while (p != (const ExceptionInfo *) NULL) { if ((p->severity >= WarningException) && (p->severity < ErrorException)) MagickWarning(p->severity,p->reason,p->description); if ((p->severity >= ErrorException) && (p->severity < FatalErrorException)) MagickError(p->severity,p->reason,p->description); if (p->severity >= FatalErrorException) MagickFatalError(p->severity,p->reason,p->description); p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *) exception->exceptions); } UnlockSemaphoreInfo(exception->semaphore); ClearMagickException(exception); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + G e t M a g i c I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetMagicInfo() searches the magic list for the specified name and if found % returns attributes for that magic. % % The format of the GetMagicInfo method is: % % const MagicInfo *GetMagicInfo(const unsigned char *magic, % const size_t length,ExceptionInfo *exception) % % A description of each parameter follows: % % o magic: A binary string generally representing the first few characters % of the image file or blob. % % o length: the length of the binary signature. % % o exception: return any errors or warnings in this structure. % */ MagickExport const MagicInfo *GetMagicInfo(const unsigned char *magic, const size_t length,ExceptionInfo *exception) { register const MagicInfo *p; assert(exception != (ExceptionInfo *) NULL); if (IsMagicCacheInstantiated(exception) == MagickFalse) return((const MagicInfo *) NULL); /* Search for magic tag. */ LockSemaphoreInfo(magic_semaphore); ResetLinkedListIterator(magic_cache); p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache); if (magic == (const unsigned char *) NULL) { UnlockSemaphoreInfo(magic_semaphore); return(p); } while (p != (const MagicInfo *) NULL) { assert(p->offset >= 0); if (((size_t) (p->offset+p->length) <= length) && (memcmp(magic+p->offset,p->magic,p->length) == 0)) break; p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache); } if (p != (const MagicInfo *) NULL) (void) InsertValueInLinkedList(magic_cache,0, RemoveElementByValueFromLinkedList(magic_cache,p)); UnlockSemaphoreInfo(magic_semaphore); return(p); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % S e t M a g i c k S e c u r i t y P o l i c y % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % SetMagickSecurityPolicy() sets the ImageMagick security policy. It returns % MagickFalse if the policy is already set or if the policy does not parse. % % The format of the SetMagickSecurityPolicy method is: % % MagickBooleanType SetMagickSecurityPolicy(const char *policy, % ExceptionInfo *exception) % % A description of each parameter follows: % % o policy: the security policy in the XML format. % % o exception: return any errors or warnings in this structure. % */ MagickExport MagickBooleanType SetMagickSecurityPolicy(const char *policy, ExceptionInfo *exception) { PolicyInfo *p; MagickBooleanType status; assert(exception != (ExceptionInfo *) NULL); if (policy == (const char *) NULL) return(MagickFalse); if (IsPolicyCacheInstantiated(exception) == MagickFalse) return(MagickFalse); LockSemaphoreInfo(policy_semaphore); ResetLinkedListIterator(policy_cache); p=(PolicyInfo *) GetNextValueInLinkedList(policy_cache); if ((p != (PolicyInfo *) NULL) && (p->domain != UndefinedPolicyDomain)) { UnlockSemaphoreInfo(policy_semaphore); return(MagickFalse); } UnlockSemaphoreInfo(policy_semaphore); status=LoadPolicyCache(policy_cache,policy,"[user-policy]",0,exception); if (status == MagickFalse) return(MagickFalse); return(ResourceComponentGenesis()); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + G e t C o n f i g u r e I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetConfigureInfo() searches the configure list for the specified name and if % found returns attributes for that element. % % The format of the GetConfigureInfo method is: % % const ConfigureInfo *GetConfigureInfo(const char *name, % ExceptionInfo *exception) % % A description of each parameter follows: % % o configure_info: GetConfigureInfo() searches the configure list for the % specified name and if found returns attributes for that element. % % o name: the configure name. % % o exception: return any errors or warnings in this structure. % */ MagickExport const ConfigureInfo *GetConfigureInfo(const char *name, ExceptionInfo *exception) { register const ConfigureInfo *p; assert(exception != (ExceptionInfo *) NULL); if ((configure_list == (LinkedListInfo *) NULL) || (instantiate_configure == MagickFalse)) if (InitializeConfigureList(exception) == MagickFalse) return((const ConfigureInfo *) NULL); if ((configure_list == (LinkedListInfo *) NULL) || (IsLinkedListEmpty(configure_list) != MagickFalse)) return((const ConfigureInfo *) NULL); if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0)) return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0)); /* Search for configure tag. */ LockSemaphoreInfo(configure_semaphore); ResetLinkedListIterator(configure_list); p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); while (p != (const ConfigureInfo *) NULL) { if (LocaleCompare(name,p->name) == 0) break; p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); } if (p != (ConfigureInfo *) NULL) (void) InsertValueInLinkedList(configure_list,0, RemoveElementByValueFromLinkedList(configure_list,p)); UnlockSemaphoreInfo(configure_semaphore); return(p); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + G e t M a g i c I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetMagicInfo() searches the magic list for the specified name and if found % returns attributes for that magic. % % The format of the GetMagicInfo method is: % % const MagicInfo *GetMagicInfo(const unsigned char *magic, % const size_t length,ExceptionInfo *exception) % % A description of each parameter follows: % % o magic: A binary string generally representing the first few characters % of the image file or blob. % % o length: The length of the binary signature. % % o exception: Return any errors or warnings in this structure. % */ MagickExport const MagicInfo *GetMagicInfo(const unsigned char *magic, const size_t length,ExceptionInfo *exception) { register const MagicInfo *p; assert(exception != (ExceptionInfo *) NULL); if ((magic_list == (LinkedListInfo *) NULL) || (instantiate_magic == MagickFalse)) if (InitializeMagicList(exception) == MagickFalse) return((const MagicInfo *) NULL); if ((magic_list == (LinkedListInfo *) NULL) || (IsLinkedListEmpty(magic_list) != MagickFalse)) return((const MagicInfo *) NULL); if ((magic == (const unsigned char *) NULL) || (length == 0)) return((const MagicInfo *) GetValueFromLinkedList(magic_list,0)); if (length == 0) return((const MagicInfo *) NULL); /* Search for requested magic. */ AcquireSemaphoreInfo(&magic_semaphore); ResetLinkedListIterator(magic_list); p=(const MagicInfo *) GetNextValueInLinkedList(magic_list); while (p != (const MagicInfo *) NULL) { assert(p->offset >= 0); if (((size_t) (p->offset+p->length) <= length) && (memcmp(magic+p->offset,p->magic,p->length) == 0)) break; p=(const MagicInfo *) GetNextValueInLinkedList(magic_list); } RelinquishSemaphoreInfo(magic_semaphore); return((const MagicInfo *) p); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t M a g i c P a t t e r n E x t e n t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetMagicPatternExtent() returns the the extent of the buffer that is % required to check all the MagickInfos. It returns zero if the list is empty. % % The format of the GetMagicPatternExtent method is: % % size_t GetMagicPatternExtent(ExceptionInfo *exception) % % A description of each parameter follows: % % o exception: return any errors or warnings in this structure. % */ MagickExport size_t GetMagicPatternExtent(ExceptionInfo *exception) { register const MagicInfo *p; size_t magickSize, max; static size_t size=0; assert(exception != (ExceptionInfo *) NULL); if ((size != 0) || (IsMagicCacheInstantiated(exception) == MagickFalse)) return(size); LockSemaphoreInfo(magic_semaphore); ResetLinkedListIterator(magic_cache); max=0; p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache); while (p != (const MagicInfo *) NULL) { magickSize=(size_t) (p->offset+p->length); if (magickSize > max) max=magickSize; p=(const MagicInfo *) GetNextValueInLinkedList(magic_cache); } size=max; UnlockSemaphoreInfo(magic_semaphore); return(size); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % I n h e r i t E x c e p t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % InheritException() inherits an exception from a related exception. % % The format of the InheritException method is: % % InheritException(ExceptionInfo *exception,const ExceptionInfo *relative) % % A description of each parameter follows: % % o exception: the exception info. % % o relative: the related exception info. % */ MagickExport void InheritException(ExceptionInfo *exception, const ExceptionInfo *relative) { register const ExceptionInfo *p; assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); assert(relative != (ExceptionInfo *) NULL); assert(relative->signature == MagickSignature); assert(exception != relative); if (relative->exceptions == (void *) NULL) return; LockSemaphoreInfo(relative->semaphore); ResetLinkedListIterator((LinkedListInfo *) relative->exceptions); p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *) relative->exceptions); while (p != (const ExceptionInfo *) NULL) { (void) ThrowException(exception,p->severity,p->reason,p->description); p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *) relative->exceptions); } UnlockSemaphoreInfo(relative->semaphore); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + G e t C o n f i g u r e I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetConfigureInfo() searches the configure list for the specified name and if % found returns attributes for that element. % % The format of the GetConfigureInfo method is: % % const ConfigureInfo *GetConfigureInfo(const char *name, % ExceptionInfo *exception) % % A description of each parameter follows: % % o configure_info: GetConfigureInfo() searches the configure list for the % specified name and if found returns attributes for that element. % % o name: The configure name. % % o exception: Return any errors or warnings in this structure. % */ WizardExport const ConfigureInfo *GetConfigureInfo(const char *name, ExceptionInfo *exception) { register const ConfigureInfo *p; assert(exception != (ExceptionInfo *) NULL); if (IsConfigureCacheInstantiated(exception) == WizardFalse) return((const ConfigureInfo *) NULL); /* Search for named configure. */ LockSemaphoreInfo(configure_semaphore); ResetLinkedListIterator(configure_cache); p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache); if ((name == (const char *) NULL) || (strcasecmp(name,"*") == 0)) { UnlockSemaphoreInfo(configure_semaphore); return(p); } while (p != (const ConfigureInfo *) NULL) { if (strcasecmp(name,p->name) == 0) break; p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_cache); } if (p == (ConfigureInfo *) NULL) (void) ThrowWizardException(exception,GetWizardModule(),OptionWarning, "no such configure list `%s'",name); else (void) InsertValueInLinkedList(configure_cache,0, RemoveElementByValueFromLinkedList(configure_cache,p)); UnlockSemaphoreInfo(configure_semaphore); return(p); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + G e t P o l i c y I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetPolicyInfo() searches the policy list for the specified name and if found % returns attributes for that policy. % % The format of the GetPolicyInfo method is: % % PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception) % % A description of each parameter follows: % % o name: the policy name. % % o exception: return any errors or warnings in this structure. % */ static PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception) { char policyname[MaxTextExtent]; register PolicyInfo *p; register char *q; assert(exception != (ExceptionInfo *) NULL); if ((policy_list == (LinkedListInfo *) NULL) || (instantiate_policy == MagickFalse)) if (InitializePolicyList(exception) == MagickFalse) return((PolicyInfo *) NULL); if ((policy_list == (LinkedListInfo *) NULL) || (IsLinkedListEmpty(policy_list) != MagickFalse)) return((PolicyInfo *) NULL); if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0)) return((PolicyInfo *) GetValueFromLinkedList(policy_list,0)); /* Strip names of whitespace. */ (void) CopyMagickString(policyname,name,MaxTextExtent); for (q=policyname; *q != '\0'; q++) { if (isspace((int) ((unsigned char) *q)) == 0) continue; (void) CopyMagickString(q,q+1,MaxTextExtent); q--; } /* Search for policy tag. */ LockSemaphoreInfo(policy_semaphore); ResetLinkedListIterator(policy_list); p=(PolicyInfo *) GetNextValueInLinkedList(policy_list); while (p != (PolicyInfo *) NULL) { if (LocaleCompare(policyname,p->name) == 0) break; p=(PolicyInfo *) GetNextValueInLinkedList(policy_list); } if (p != (PolicyInfo *) NULL) (void) InsertValueInLinkedList(policy_list,0, RemoveElementByValueFromLinkedList(policy_list,p)); UnlockSemaphoreInfo(policy_semaphore); return(p); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % I s R i g h t s A u t h o r i z e d % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % IsRightsAuthorized() returns MagickTrue if the policy authorizes the % requested rights for the specified domain. % % The format of the IsRightsAuthorized method is: % % MagickBooleanType IsRightsAuthorized(const PolicyDomain domain, % const PolicyRights rights,const char *pattern) % % A description of each parameter follows: % % o domain: the policy domain. % % o rights: the policy rights. % % o pattern: the coder, delegate, filter, or path pattern. % */ MagickExport MagickBooleanType IsRightsAuthorized(const PolicyDomain domain, const PolicyRights rights,const char *pattern) { const PolicyInfo *policy_info; ExceptionInfo *exception; MagickBooleanType authorized; register PolicyInfo *p; (void) LogMagickEvent(PolicyEvent,GetMagickModule(), "Domain: %s; rights=%s; pattern=\"%s\" ...", CommandOptionToMnemonic(MagickPolicyDomainOptions,domain), CommandOptionToMnemonic(MagickPolicyRightsOptions,rights),pattern); exception=AcquireExceptionInfo(); policy_info=GetPolicyInfo("*",exception); exception=DestroyExceptionInfo(exception); if (policy_info == (PolicyInfo *) NULL) return(MagickTrue); authorized=MagickTrue; LockSemaphoreInfo(policy_semaphore); ResetLinkedListIterator(policy_list); p=(PolicyInfo *) GetNextValueInLinkedList(policy_list); while ((p != (PolicyInfo *) NULL) && (authorized != MagickFalse)) { if ((p->domain == domain) && (GlobExpression(pattern,p->pattern,MagickFalse) != MagickFalse)) { if (((rights & ReadPolicyRights) != 0) && ((p->rights & ReadPolicyRights) == 0)) authorized=MagickFalse; if (((rights & WritePolicyRights) != 0) && ((p->rights & WritePolicyRights) == 0)) authorized=MagickFalse; if (((rights & ExecutePolicyRights) != 0) && ((p->rights & ExecutePolicyRights) == 0)) authorized=MagickFalse; } p=(PolicyInfo *) GetNextValueInLinkedList(policy_list); } UnlockSemaphoreInfo(policy_semaphore); return(authorized); }
static MagickBooleanType SetPolicyValue(const PolicyDomain domain, const char *name,const char *value) { MagickBooleanType status; register PolicyInfo *p; status=MagickTrue; LockSemaphoreInfo(policy_semaphore); ResetLinkedListIterator(policy_cache); p=(PolicyInfo *) GetNextValueInLinkedList(policy_cache); while (p != (PolicyInfo *) NULL) { if ((p->domain == domain) && (LocaleCompare(name,p->name) == 0)) break; p=(PolicyInfo *) GetNextValueInLinkedList(policy_cache); } if (p != (PolicyInfo *) NULL) { if (p->value != (char *) NULL) p->value=DestroyString(p->value); } else { p=(PolicyInfo *) AcquireCriticalMemory(sizeof(*p)); (void) memset(p,0,sizeof(*p)); p->exempt=MagickFalse; p->signature=MagickCoreSignature; p->domain=domain; p->name=ConstantString(name); status=AppendValueToLinkedList(policy_cache,p); } p->value=ConstantString(value); UnlockSemaphoreInfo(policy_semaphore); if (status == MagickFalse) p=(PolicyInfo *) RelinquishMagickMemory(p); return(status); }
int HasError(ExceptionInfo *exception) { register const ExceptionInfo *p; int result = 0; assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); if (exception->exceptions == (void *) NULL) return 0; if (exception->semaphore == (void *) NULL) return 0; LockSemaphoreInfo(exception->semaphore); ResetLinkedListIterator((LinkedListInfo *) exception->exceptions); p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *) exception->exceptions); while (p != (const ExceptionInfo *) NULL) { if (p->severity >= ErrorException) result = 1; p=(const ExceptionInfo *) GetNextValueInLinkedList((LinkedListInfo *) exception->exceptions); } UnlockSemaphoreInfo(exception->semaphore); return result; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G e t C o n f i g u r e O p t i o n s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetConfigureOptions() returns any Magick configuration options associated % with the specified filename. % % The format of the GetConfigureOptions method is: % % LinkedListInfo *GetConfigureOptions(const char *filename, % ExceptionInfo *exception) % % A description of each parameter follows: % % o filename: the configure file name. % % o exception: return any errors or warnings in this structure. % */ MagickExport LinkedListInfo *GetConfigureOptions(const char *filename, ExceptionInfo *exception) { char path[MaxTextExtent]; const char *element; LinkedListInfo *options, *paths; StringInfo *xml; assert(filename != (const char *) NULL); (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); assert(exception != (ExceptionInfo *) NULL); (void) CopyMagickString(path,filename,MaxTextExtent); /* Load XML from configuration files to linked-list. */ options=NewLinkedList(0); paths=GetConfigurePaths(filename,exception); if (paths != (LinkedListInfo *) NULL) { ResetLinkedListIterator(paths); element=(const char *) GetNextValueInLinkedList(paths); while (element != (const char *) NULL) { (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename); (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Searching for configure file: \"%s\"",path); xml=ConfigureFileToStringInfo(path); if (xml != (StringInfo *) NULL) (void) AppendValueToLinkedList(options,xml); element=(const char *) GetNextValueInLinkedList(paths); } paths=DestroyLinkedList(paths,RelinquishMagickMemory); } #if defined(MAGICKCORE_WINDOWS_SUPPORT) if (GetNumberOfElementsInLinkedList(options) == 0) { char *blob; blob=(char *) NTResourceToBlob(filename); if (blob != (char *) NULL) { xml=AcquireStringInfo(0); SetStringInfoLength(xml,strlen(blob)+1); SetStringInfoDatum(xml,(unsigned char *) blob); SetStringInfoPath(xml,filename); (void) AppendValueToLinkedList(options,xml); } } #endif if (GetNumberOfElementsInLinkedList(options) == 0) (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning, "UnableToOpenConfigureFile","`%s'",filename); ResetLinkedListIterator(options); return(options); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + G e t P o l i c y I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetPolicyInfo() searches the policy list for the specified name and if found % returns attributes for that policy. % % The format of the GetPolicyInfo method is: % % PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception) % % A description of each parameter follows: % % o name: the policy name. % % o exception: return any errors or warnings in this structure. % */ static PolicyInfo *GetPolicyInfo(const char *name,ExceptionInfo *exception) { char policyname[MagickPathExtent]; PolicyDomain domain; register PolicyInfo *p; register char *q; assert(exception != (ExceptionInfo *) NULL); if (IsPolicyCacheInstantiated(exception) == MagickFalse) return((PolicyInfo *) NULL); /* Strip names of whitespace. */ *policyname='\0'; if (name != (const char *) NULL) (void) CopyMagickString(policyname,name,MagickPathExtent); for (q=policyname; *q != '\0'; q++) { if (isspace((int) ((unsigned char) *q)) == 0) continue; (void) CopyMagickString(q,q+1,MagickPathExtent); q--; } /* Strip domain from policy name (e.g. resource:map). */ domain=UndefinedPolicyDomain; for (q=policyname; *q != '\0'; q++) { if (*q != ':') continue; *q='\0'; domain=(PolicyDomain) ParseCommandOption(MagickPolicyDomainOptions, MagickTrue,policyname); (void) CopyMagickString(policyname,q+1,MagickPathExtent); break; } /* Search for policy tag. */ LockSemaphoreInfo(policy_semaphore); ResetLinkedListIterator(policy_cache); p=(PolicyInfo *) GetNextValueInLinkedList(policy_cache); if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0)) { UnlockSemaphoreInfo(policy_semaphore); return(p); } while (p != (PolicyInfo *) NULL) { if ((domain == UndefinedPolicyDomain) || (p->domain == domain)) if (LocaleCompare(policyname,p->name) == 0) break; p=(PolicyInfo *) GetNextValueInLinkedList(policy_cache); } if (p != (PolicyInfo *) NULL) (void) InsertValueInLinkedList(policy_cache,0, RemoveElementByValueFromLinkedList(policy_cache,p)); UnlockSemaphoreInfo(policy_semaphore); return(p); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d C A C H E I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadMPCImage() reads an Magick Persistent Cache image file and returns % it. It allocates the memory necessary for the new Image structure and % returns a pointer to the new image. % % The format of the ReadMPCImage method is: % % Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception) % % Decompression code contributed by Kyle Shorter. % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception) { char cache_filename[MaxTextExtent], id[MaxTextExtent], keyword[MaxTextExtent], *options; const unsigned char *p; GeometryInfo geometry_info; Image *image; int c; LinkedListInfo *profiles; MagickBooleanType status; MagickOffsetType offset; MagickStatusType flags; register long i; size_t length; ssize_t count; StringInfo *profile; unsigned long depth, quantum_depth; /* Open image file. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { image=DestroyImageList(image); return((Image *) NULL); } (void) CopyMagickString(cache_filename,image->filename,MaxTextExtent); AppendImageFormat("cache",cache_filename); c=ReadBlobByte(image); if (c == EOF) { image=DestroyImage(image); return((Image *) NULL); } *id='\0'; (void) ResetMagickMemory(keyword,0,sizeof(keyword)); offset=0; do { /* Decode image header; header terminates one character beyond a ':'. */ profiles=(LinkedListInfo *) NULL; length=MaxTextExtent; options=AcquireString((char *) NULL); quantum_depth=MAGICKCORE_QUANTUM_DEPTH; image->depth=8; image->compression=NoCompression; while ((isgraph(c) != MagickFalse) && (c != (int) ':')) { register char *p; if (c == (int) '{') { char *comment; /* Read comment-- any text between { }. */ length=MaxTextExtent; comment=AcquireString((char *) NULL); for (p=comment; comment != (char *) NULL; p++) { c=ReadBlobByte(image); if ((c == EOF) || (c == (int) '}')) break; if ((size_t) (p-comment+1) >= length) { *p='\0'; length<<=1; comment=(char *) ResizeQuantumMemory(comment,length+ MaxTextExtent,sizeof(*comment)); if (comment == (char *) NULL) break; p=comment+strlen(comment); } *p=(char) c; } if (comment == (char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); *p='\0'; (void) SetImageProperty(image,"comment",comment); comment=DestroyString(comment); c=ReadBlobByte(image); } else if (isalnum(c) != MagickFalse) { /* Get the keyword. */ p=keyword; do { if (isspace((int) ((unsigned char) c)) != 0) break; if (c == (int) '=') break; if ((size_t) (p-keyword) < (MaxTextExtent-1)) *p++=(char) c; c=ReadBlobByte(image); } while (c != EOF); *p='\0'; p=options; while (isspace((int) ((unsigned char) c)) != 0) c=ReadBlobByte(image); if (c == (int) '=') { /* Get the keyword value. */ c=ReadBlobByte(image); while ((c != (int) '}') && (c != EOF)) { if ((size_t) (p-options+1) >= length) { *p='\0'; length<<=1; options=(char *) ResizeQuantumMemory(options,length+ MaxTextExtent,sizeof(*options)); if (options == (char *) NULL) break; p=options+strlen(options); } if (options == (char *) NULL) ThrowReaderException(ResourceLimitError, "MemoryAllocationFailed"); *p++=(char) c; c=ReadBlobByte(image); if (*options != '{') if (isspace((int) ((unsigned char) c)) != 0) break; } } *p='\0'; if (*options == '{') (void) CopyMagickString(options,options+1,MaxTextExtent); /* Assign a value to the specified keyword. */ switch (*keyword) { case 'b': case 'B': { if (LocaleCompare(keyword,"background-color") == 0) { (void) QueryColorDatabase(options,&image->background_color, exception); break; } if (LocaleCompare(keyword,"blue-primary") == 0) { flags=ParseGeometry(options,&geometry_info); image->chromaticity.blue_primary.x=geometry_info.rho; image->chromaticity.blue_primary.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) image->chromaticity.blue_primary.y= image->chromaticity.blue_primary.x; break; } if (LocaleCompare(keyword,"border-color") == 0) { (void) QueryColorDatabase(options,&image->border_color, exception); break; } (void) SetImageProperty(image,keyword,options); break; } case 'c': case 'C': { if (LocaleCompare(keyword,"class") == 0) { long storage_class; storage_class=ParseMagickOption(MagickClassOptions, MagickFalse,options); if (storage_class < 0) break; image->storage_class=(ClassType) storage_class; break; } if (LocaleCompare(keyword,"colors") == 0) { image->colors=StringToUnsignedLong(options); break; } if (LocaleCompare(keyword,"colorspace") == 0) { long colorspace; colorspace=ParseMagickOption(MagickColorspaceOptions, MagickFalse,options); if (colorspace < 0) break; image->colorspace=(ColorspaceType) colorspace; break; } if (LocaleCompare(keyword,"compression") == 0) { long compression; compression=ParseMagickOption(MagickCompressOptions, MagickFalse,options); if (compression < 0) break; image->compression=(CompressionType) compression; break; } if (LocaleCompare(keyword,"columns") == 0) { image->columns=StringToUnsignedLong(options); break; } (void) SetImageProperty(image,keyword,options); break; } case 'd': case 'D': { if (LocaleCompare(keyword,"delay") == 0) { image->delay=StringToUnsignedLong(options); break; } if (LocaleCompare(keyword,"depth") == 0) { image->depth=StringToUnsignedLong(options); break; } if (LocaleCompare(keyword,"dispose") == 0) { long dispose; dispose=ParseMagickOption(MagickDisposeOptions,MagickFalse, options); if (dispose < 0) break; image->dispose=(DisposeType) dispose; break; } (void) SetImageProperty(image,keyword,options); break; } case 'e': case 'E': { if (LocaleCompare(keyword,"endian") == 0) { long endian; endian=ParseMagickOption(MagickEndianOptions,MagickFalse, options); if (endian < 0) break; image->endian=(EndianType) endian; break; } if (LocaleCompare(keyword,"error") == 0) { image->error.mean_error_per_pixel=StringToDouble(options); break; } (void) SetImageProperty(image,keyword,options); break; } case 'g': case 'G': { if (LocaleCompare(keyword,"gamma") == 0) { image->gamma=StringToDouble(options); break; } if (LocaleCompare(keyword,"green-primary") == 0) { flags=ParseGeometry(options,&geometry_info); image->chromaticity.green_primary.x=geometry_info.rho; image->chromaticity.green_primary.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) image->chromaticity.green_primary.y= image->chromaticity.green_primary.x; break; } (void) SetImageProperty(image,keyword,options); break; } case 'i': case 'I': { if (LocaleCompare(keyword,"id") == 0) { (void) CopyMagickString(id,options,MaxTextExtent); break; } if (LocaleCompare(keyword,"iterations") == 0) { image->iterations=StringToUnsignedLong(options); break; } (void) SetImageProperty(image,keyword,options); break; } case 'm': case 'M': { if (LocaleCompare(keyword,"matte") == 0) { long matte; matte=ParseMagickOption(MagickBooleanOptions,MagickFalse, options); if (matte < 0) break; image->matte=(MagickBooleanType) matte; break; } if (LocaleCompare(keyword,"matte-color") == 0) { (void) QueryColorDatabase(options,&image->matte_color, exception); break; } if (LocaleCompare(keyword,"maximum-error") == 0) { image->error.normalized_maximum_error=StringToDouble(options); break; } if (LocaleCompare(keyword,"mean-error") == 0) { image->error.normalized_mean_error=StringToDouble(options); break; } if (LocaleCompare(keyword,"montage") == 0) { (void) CloneString(&image->montage,options); break; } (void) SetImageProperty(image,keyword,options); break; } case 'o': case 'O': { if (LocaleCompare(keyword,"opaque") == 0) { long matte; matte=ParseMagickOption(MagickBooleanOptions,MagickFalse, options); if (matte < 0) break; image->matte=(MagickBooleanType) matte; break; } if (LocaleCompare(keyword,"orientation") == 0) { long orientation; orientation=ParseMagickOption(MagickOrientationOptions, MagickFalse,options); if (orientation < 0) break; image->orientation=(OrientationType) orientation; break; } (void) SetImageProperty(image,keyword,options); break; } case 'p': case 'P': { if (LocaleCompare(keyword,"page") == 0) { char *geometry; geometry=GetPageGeometry(options); (void) ParseAbsoluteGeometry(geometry,&image->page); geometry=DestroyString(geometry); break; } if ((LocaleNCompare(keyword,"profile:",8) == 0) || (LocaleNCompare(keyword,"profile-",8) == 0)) { if (profiles == (LinkedListInfo *) NULL) profiles=NewLinkedList(0); (void) AppendValueToLinkedList(profiles, AcquireString(keyword+8)); profile=AcquireStringInfo((size_t) StringToLong(options)); (void) SetImageProfile(image,keyword+8,profile); profile=DestroyStringInfo(profile); break; } (void) SetImageProperty(image,keyword,options); break; } case 'q': case 'Q': { if (LocaleCompare(keyword,"quality") == 0) { image->quality=StringToUnsignedLong(options); break; } if (LocaleCompare(keyword,"quantum-depth") == 0) { quantum_depth=StringToUnsignedLong(options); break; } (void) SetImageProperty(image,keyword,options); break; } case 'r': case 'R': { if (LocaleCompare(keyword,"red-primary") == 0) { flags=ParseGeometry(options,&geometry_info); image->chromaticity.red_primary.x=geometry_info.rho; if ((flags & SigmaValue) != 0) image->chromaticity.red_primary.y=geometry_info.sigma; break; } if (LocaleCompare(keyword,"rendering-intent") == 0) { long rendering_intent; rendering_intent=ParseMagickOption(MagickIntentOptions, MagickFalse,options); if (rendering_intent < 0) break; image->rendering_intent=(RenderingIntent) rendering_intent; break; } if (LocaleCompare(keyword,"resolution") == 0) { flags=ParseGeometry(options,&geometry_info); image->x_resolution=geometry_info.rho; image->y_resolution=geometry_info.sigma; if ((flags & SigmaValue) == 0) image->y_resolution=image->x_resolution; break; } if (LocaleCompare(keyword,"rows") == 0) { image->rows=StringToUnsignedLong(options); break; } (void) SetImageProperty(image,keyword,options); break; } case 's': case 'S': { if (LocaleCompare(keyword,"scene") == 0) { image->scene=StringToUnsignedLong(options); break; } (void) SetImageProperty(image,keyword,options); break; } case 't': case 'T': { if (LocaleCompare(keyword,"ticks-per-second") == 0) { image->ticks_per_second=(long) StringToLong(options); break; } if (LocaleCompare(keyword,"tile-offset") == 0) { char *geometry; geometry=GetPageGeometry(options); (void) ParseAbsoluteGeometry(geometry,&image->tile_offset); geometry=DestroyString(geometry); } if (LocaleCompare(keyword,"type") == 0) { long type; type=ParseMagickOption(MagickTypeOptions,MagickFalse, options); if (type < 0) break; image->type=(ImageType) type; break; } (void) SetImageProperty(image,keyword,options); break; } case 'u': case 'U': { if (LocaleCompare(keyword,"units") == 0) { long units; units=ParseMagickOption(MagickResolutionOptions,MagickFalse, options); if (units < 0) break; image->units=(ResolutionType) units; break; } (void) SetImageProperty(image,keyword,options); break; } case 'w': case 'W': { if (LocaleCompare(keyword,"white-point") == 0) { flags=ParseGeometry(options,&geometry_info); image->chromaticity.white_point.x=geometry_info.rho; image->chromaticity.white_point.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) image->chromaticity.white_point.y= image->chromaticity.white_point.x; break; } (void) SetImageProperty(image,keyword,options); break; } default: { (void) SetImageProperty(image,keyword,options); break; } } } else c=ReadBlobByte(image); while (isspace((int) ((unsigned char) c)) != 0) c=ReadBlobByte(image); } options=DestroyString(options); (void) ReadBlobByte(image); /* Verify that required image information is defined. */ if ((LocaleCompare(id,"MagickCache") != 0) || (image->storage_class == UndefinedClass) || (image->compression == UndefinedCompression) || (image->columns == 0) || (image->rows == 0)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); if (quantum_depth != MAGICKCORE_QUANTUM_DEPTH) ThrowReaderException(CacheError,"InconsistentPersistentCacheDepth"); if (image->montage != (char *) NULL) { register char *p; /* Image directory. */ length=MaxTextExtent; image->directory=AcquireString((char *) NULL); p=image->directory; do { *p='\0'; if ((strlen(image->directory)+MaxTextExtent) >= length) { /* Allocate more memory for the image directory. */ length<<=1; image->directory=(char *) ResizeQuantumMemory(image->directory, length+MaxTextExtent,sizeof(*image->directory)); if (image->directory == (char *) NULL) ThrowReaderException(CorruptImageError,"UnableToReadImageData"); p=image->directory+strlen(image->directory); } c=ReadBlobByte(image); *p++=(char) c; } while (c != (int) '\0'); } if (profiles != (LinkedListInfo *) NULL) { const char *name; const StringInfo *profile; register unsigned char *p; /* Read image profiles. */ ResetLinkedListIterator(profiles); name=(const char *) GetNextValueInLinkedList(profiles); while (name != (const char *) NULL) { profile=GetImageProfile(image,name); if (profile != (StringInfo *) NULL) { p=GetStringInfoDatum(profile); count=ReadBlob(image,GetStringInfoLength(profile),p); } name=(const char *) GetNextValueInLinkedList(profiles); } profiles=DestroyLinkedList(profiles,RelinquishMagickMemory); } depth=GetImageQuantumDepth(image,MagickFalse); if (image->storage_class == PseudoClass) { /* Create image colormap. */ if (AcquireImageColormap(image,image->colors) == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); if (image->colors != 0) { size_t packet_size; unsigned char *colormap; /* Read image colormap from file. */ packet_size=(size_t) (3UL*depth/8UL); colormap=(unsigned char *) AcquireQuantumMemory(image->colors, packet_size*sizeof(*colormap)); if (colormap == (unsigned char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); count=ReadBlob(image,packet_size*image->colors,colormap); if (count != (ssize_t) (packet_size*image->colors)) ThrowReaderException(CorruptImageError, "InsufficientImageDataInFile"); p=colormap; switch (depth) { default: ThrowReaderException(CorruptImageError, "ImageDepthNotSupported"); case 8: { unsigned char pixel; for (i=0; i < (long) image->colors; i++) { p=PushCharPixel(p,&pixel); image->colormap[i].red=ScaleCharToQuantum(pixel); p=PushCharPixel(p,&pixel); image->colormap[i].green=ScaleCharToQuantum(pixel); p=PushCharPixel(p,&pixel); image->colormap[i].blue=ScaleCharToQuantum(pixel); } break; } case 16: { unsigned short pixel; for (i=0; i < (long) image->colors; i++) { p=PushShortPixel(MSBEndian,p,&pixel); image->colormap[i].red=ScaleShortToQuantum(pixel); p=PushShortPixel(MSBEndian,p,&pixel); image->colormap[i].green=ScaleShortToQuantum(pixel); p=PushShortPixel(MSBEndian,p,&pixel); image->colormap[i].blue=ScaleShortToQuantum(pixel); } break; } case 32: { unsigned long pixel; for (i=0; i < (long) image->colors; i++) { p=PushLongPixel(MSBEndian,p,&pixel); image->colormap[i].red=ScaleLongToQuantum(pixel); p=PushLongPixel(MSBEndian,p,&pixel); image->colormap[i].green=ScaleLongToQuantum(pixel); p=PushLongPixel(MSBEndian,p,&pixel); image->colormap[i].blue=ScaleLongToQuantum(pixel); } break; } } colormap=(unsigned char *) RelinquishMagickMemory(colormap); } } if (EOFBlob(image) != MagickFalse) { ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); break; } if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) if (image->scene >= (image_info->scene+image_info->number_scenes-1)) break; /* Attach persistent pixel cache. */ status=PersistPixelCache(image,cache_filename,MagickTrue,&offset,exception); if (status == MagickFalse) ThrowReaderException(CacheError,"UnableToPersistPixelCache"); /* Proceed to next image. */ do { c=ReadBlobByte(image); } while ((isgraph(c) == MagickFalse) && (c != EOF)); if (c != EOF) { /* Allocate next image structure. */ AcquireNextImage(image_info,image); if (GetNextImageInList(image) == (Image *) NULL) { image=DestroyImageList(image); return((Image *) NULL); } image=SyncNextImageInList(image); status=SetImageProgress(image,LoadImagesTag,TellBlob(image), GetBlobSize(image)); if (status == MagickFalse) break; } } while (c != EOF); (void) CloseBlob(image); return(GetFirstImageInList(image)); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + G e t M i m e I n f o % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GetMimeInfo() attempts to classify the content to identify which mime type % is associated with the content, if any. % % The format of the GetMimeInfo method is: % % const MimeInfo *GetMimeInfo(const char *filename, % const unsigned char *magic,const size_t length, % ExceptionInfo *exception) % % A description of each parameter follows: % % o filename: If we cannot not classify the string, we attempt to classify % based on the filename (e.g. *.pdf returns application/pdf). % % o magic: A binary string generally representing the first few characters % of the image file or blob. % % o length: the length of the binary signature. % % o exception: return any errors or warnings in this structure. % */ MagickExport const MimeInfo *GetMimeInfo(const char *filename, const unsigned char *magic,const size_t length,ExceptionInfo *exception) { const MimeInfo *mime_info; EndianType endian; register const MimeInfo *p; register const unsigned char *q; register ssize_t i; ssize_t value; unsigned long lsb_first; assert(exception != (ExceptionInfo *) NULL); if (IsMimeCacheInstantiated(exception) == MagickFalse) return((const MimeInfo *) NULL); /* Search for mime tag. */ mime_info=(const MimeInfo *) NULL; lsb_first=1; LockSemaphoreInfo(mime_semaphore); ResetLinkedListIterator(mime_cache); p=(const MimeInfo *) GetNextValueInLinkedList(mime_cache); if ((magic == (const unsigned char *) NULL) || (length == 0)) { UnlockSemaphoreInfo(mime_semaphore); return(p); } while (p != (const MimeInfo *) NULL) { assert(p->offset >= 0); if (mime_info != (const MimeInfo *) NULL) if (p->priority > mime_info->priority) { p=(const MimeInfo *) GetNextValueInLinkedList(mime_cache); continue; } if ((p->pattern != (char *) NULL) && (filename != (char *) NULL)) { if (GlobExpression(filename,p->pattern,MagickFalse) != MagickFalse) mime_info=p; p=(const MimeInfo *) GetNextValueInLinkedList(mime_cache); continue; } switch (p->data_type) { case ByteData: { if ((size_t) (p->offset+4) > length) break; q=magic+p->offset; value=(ssize_t) (*q++); if (p->mask == 0) { if (p->value == value) mime_info=p; } else { if ((p->value & p->mask) == value) mime_info=p; } break; } case ShortData: { if ((size_t) (p->offset+4) > length) break; q=magic+p->offset; endian=p->endian; if (p->endian == UndefinedEndian) endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian; if (endian == LSBEndian) { value=(ssize_t) (*q++); value|=(*q++) << 8; } else { value=(ssize_t) (*q++) << 8; value|=(*q++); } if (p->mask == 0) { if (p->value == value) mime_info=p; } else { if ((p->value & p->mask) == value) mime_info=p; } break; } case LongData: { if ((size_t) (p->offset+4) > length) break; q=magic+p->offset; endian=p->endian; if (p->endian == UndefinedEndian) endian=(*(char *) &lsb_first) == 1 ? LSBEndian : MSBEndian; if (endian == LSBEndian) { value=(ssize_t) (*q++); value|=((ssize_t) *q++) << 8; value|=((ssize_t) *q++) << 16; value|=((ssize_t) *q++) << 24; } else { value=(ssize_t) (*q++) << 24; value|=((ssize_t) *q++) << 16; value|=((ssize_t) *q++) << 8; value|=((ssize_t) *q++); } if (p->mask == 0) { if (p->value == value) mime_info=p; } else { if ((p->value & p->mask) == value) mime_info=p; } break; } case StringData: default: { for (i=0; i <= (ssize_t) p->extent; i++) { if ((size_t) (p->offset+i+p->length) > length) break; if (memcmp(magic+p->offset+i,p->magic,p->length) == 0) { mime_info=p; break; } } break; } } p=(const MimeInfo *) GetNextValueInLinkedList(mime_cache); } if (mime_info != (const MimeInfo *) NULL) (void) InsertValueInLinkedList(mime_cache,0, RemoveElementByValueFromLinkedList(mime_cache,p)); UnlockSemaphoreInfo(mime_semaphore); return(mime_info); }