/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G l o b E x p r e s s i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GlobExpression() returns MagickTrue if the expression matches the pattern. % % The format of the GlobExpression function is: % % MagickBooleanType GlobExpression(const char *expression, % const char *pattern,const MagickBooleanType case_insensitive) % % A description of each parameter follows: % % o expression: Specifies a pointer to a text string containing a file name. % % o pattern: Specifies a pointer to a text string containing a pattern. % % o case_insensitive: set to MagickTrue to ignore the case when matching % an expression. % */ MagickExport MagickBooleanType GlobExpression(const char *expression, const char *pattern,const MagickBooleanType case_insensitive) { MagickBooleanType done, match; register const char *p; /* Return on empty pattern or '*'. */ if (pattern == (char *) NULL) return(MagickTrue); if (GetUTFCode(pattern) == 0) return(MagickTrue); if (LocaleCompare(pattern,"*") == 0) return(MagickTrue); p=pattern+strlen(pattern)-1; if ((GetUTFCode(p) == ']') && (strchr(pattern,'[') != (char *) NULL)) { ExceptionInfo *exception; ImageInfo *image_info; /* Determine if pattern is a scene, i.e. img0001.pcd[2]. */ image_info=AcquireImageInfo(); (void) CopyMagickString(image_info->filename,pattern,MaxTextExtent); exception=AcquireExceptionInfo(); (void) SetImageInfo(image_info,MagickTrue,exception); exception=DestroyExceptionInfo(exception); if (LocaleCompare(image_info->filename,pattern) != 0) { image_info=DestroyImageInfo(image_info); return(MagickFalse); } image_info=DestroyImageInfo(image_info); } /* Evaluate glob expression. */ done=MagickFalse; while ((GetUTFCode(pattern) != 0) && (done == MagickFalse)) { if (GetUTFCode(expression) == 0) if ((GetUTFCode(pattern) != '{') && (GetUTFCode(pattern) != '*')) break; switch (GetUTFCode(pattern)) { case '\\': { pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) != 0) pattern+=GetUTFOctets(pattern); break; } case '*': { MagickBooleanType status; status=MagickFalse; pattern+=GetUTFOctets(pattern); while ((GetUTFCode(expression) != 0) && (status == MagickFalse)) { status=GlobExpression(expression,pattern,case_insensitive); expression+=GetUTFOctets(expression); } if (status != MagickFalse) { while (GetUTFCode(expression) != 0) expression+=GetUTFOctets(expression); while (GetUTFCode(pattern) != 0) pattern+=GetUTFOctets(pattern); } break; } case '[': { long c; pattern+=GetUTFOctets(pattern); for ( ; ; ) { if ((GetUTFCode(pattern) == 0) || (GetUTFCode(pattern) == ']')) { done=MagickTrue; break; } if (GetUTFCode(pattern) == '\\') { pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) == 0) { done=MagickTrue; break; } } if (GetUTFCode(pattern+GetUTFOctets(pattern)) == '-') { c=GetUTFCode(pattern); pattern+=GetUTFOctets(pattern); pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) == ']') { done=MagickTrue; break; } if (GetUTFCode(pattern) == '\\') { pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) == 0) { done=MagickTrue; break; } } if ((GetUTFCode(expression) < c) || (GetUTFCode(expression) > GetUTFCode(pattern))) { pattern+=GetUTFOctets(pattern); continue; } } else if (GetUTFCode(pattern) != GetUTFCode(expression)) { pattern+=GetUTFOctets(pattern); continue; } pattern+=GetUTFOctets(pattern); while ((GetUTFCode(pattern) != ']') && (GetUTFCode(pattern) != 0)) { if ((GetUTFCode(pattern) == '\\') && (GetUTFCode(pattern+GetUTFOctets(pattern)) > 0)) pattern+=GetUTFOctets(pattern); pattern+=GetUTFOctets(pattern); } if (GetUTFCode(pattern) != 0) { pattern+=GetUTFOctets(pattern); expression+=GetUTFOctets(expression); } break; } break; } case '?': { pattern+=GetUTFOctets(pattern); expression+=GetUTFOctets(expression); break; } case '{': { register const char *p; pattern+=GetUTFOctets(pattern); while ((GetUTFCode(pattern) != '}') && (GetUTFCode(pattern) != 0)) { p=expression; match=MagickTrue; while ((GetUTFCode(p) != 0) && (GetUTFCode(pattern) != 0) && (GetUTFCode(pattern) != ',') && (GetUTFCode(pattern) != '}') && (match != MagickFalse)) { if (GetUTFCode(pattern) == '\\') pattern+=GetUTFOctets(pattern); match=(GetUTFCode(pattern) == GetUTFCode(p)) ? MagickTrue : MagickFalse; p+=GetUTFOctets(p); pattern+=GetUTFOctets(pattern); } if (GetUTFCode(pattern) == 0) { match=MagickFalse; done=MagickTrue; break; } else if (match != MagickFalse) { expression=p; while ((GetUTFCode(pattern) != '}') && (GetUTFCode(pattern) != 0)) { pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) == '\\') { pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) == '}') pattern+=GetUTFOctets(pattern); } } } else { while ((GetUTFCode(pattern) != '}') && (GetUTFCode(pattern) != ',') && (GetUTFCode(pattern) != 0)) { pattern+=GetUTFOctets(pattern); if (GetUTFCode(pattern) == '\\') { pattern+=GetUTFOctets(pattern); if ((GetUTFCode(pattern) == '}') || (GetUTFCode(pattern) == ',')) pattern+=GetUTFOctets(pattern); } } } if (GetUTFCode(pattern) != 0) pattern+=GetUTFOctets(pattern); } break; } default: { if (case_insensitive != MagickFalse) { if (tolower((int) GetUTFCode(expression)) != tolower((int) GetUTFCode(pattern))) { done=MagickTrue; break; } } else if (GetUTFCode(expression) != GetUTFCode(pattern)) { done=MagickTrue; break; } expression+=GetUTFOctets(expression); pattern+=GetUTFOctets(pattern); } } } while (GetUTFCode(pattern) == '*') pattern+=GetUTFOctets(pattern); match=(GetUTFCode(expression) == 0) && (GetUTFCode(pattern) == 0) ? MagickTrue : MagickFalse; return(match); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + 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); }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % G l o b E x p r e s s i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GlobExpression() returns MagickTrue if the expression matches the pattern. % % The format of the GlobExpression function is: % % MagickBooleanType GlobExpression(const char *expression, % const char *pattern) % % A description of each parameter follows: % % o expression: Specifies a pointer to a text string containing a file name. % % o pattern: Specifies a pointer to a text string containing a pattern. % % */ MagickExport MagickBooleanType GlobExpression(const char *expression, const char *pattern) { MagickBooleanType done; register const char *p; /* Return on empty pattern or '*'. */ if (pattern == (char *) NULL) return(MagickTrue); if (*pattern == '\0') return(MagickTrue); if (LocaleCompare(pattern,"*") == 0) return(MagickTrue); p=pattern+strlen(pattern)-1; if ((*p == ']') && (strchr(pattern,'[') != (char *) NULL)) { ExceptionInfo exception; ImageInfo *image_info; /* Determine if pattern is a scene, i.e. img0001.pcd[2]. */ image_info=CloneImageInfo((ImageInfo *) NULL); (void) CopyMagickString(image_info->filename,pattern,MaxTextExtent); GetExceptionInfo(&exception); (void) SetImageInfo(image_info,MagickTrue,&exception); DestroyExceptionInfo(&exception); if (LocaleCompare(image_info->filename,pattern) != 0) { image_info=DestroyImageInfo(image_info); return(MagickFalse); } image_info=DestroyImageInfo(image_info); } /* Evaluate glob expression. */ done=MagickFalse; while ((*pattern != '\0') && (done == MagickFalse)) { if (*expression == '\0') if ((*pattern != '{') && (*pattern != '*')) break; switch (*pattern) { case '\\': { pattern++; if (*pattern != '\0') pattern++; break; } case '*': { MagickBooleanType status; pattern++; status=MagickFalse; while ((*expression != '\0') && (status == MagickFalse)) status=GlobExpression(expression++,pattern); if (status != MagickFalse) { while (*expression != '\0') expression++; while (*pattern != '\0') pattern++; } break; } case '[': { char c; pattern++; for ( ; ; ) { if ((*pattern == '\0') || (*pattern == ']')) { done=MagickTrue; break; } if (*pattern == '\\') { pattern++; if (*pattern == '\0') { done=MagickTrue; break; } } if (*(pattern+1) == '-') { c=(*pattern); pattern+=2; if (*pattern == ']') { done=MagickTrue; break; } if (*pattern == '\\') { pattern++; if (*pattern == '\0') { done=MagickTrue; break; } } if ((*expression < c) || (*expression > *pattern)) { pattern++; continue; } } else if (*pattern != *expression) { pattern++; continue; } pattern++; while ((*pattern != ']') && (*pattern != '\0')) { if ((*pattern == '\\') && (*(pattern+1) != '\0')) pattern++; pattern++; } if (*pattern != '\0') { pattern++; expression++; } break; } break; } case '?': { pattern++; expression++; break; } case '{': { MagickBooleanType match; register const char *p; pattern++; while ((*pattern != '}') && (*pattern != '\0')) { p=expression; match=MagickTrue; while ((*p != '\0') && (*pattern != '\0') && (*pattern != ',') && (*pattern != '}') && (match != MagickFalse)) { if (*pattern == '\\') pattern++; match=(MagickBooleanType) (*pattern == *p); p++; pattern++; } if (*pattern == '\0') { match=MagickFalse; done=MagickTrue; break; } else if (match != MagickFalse) { expression=p; while ((*pattern != '}') && (*pattern != '\0')) { pattern++; if (*pattern == '\\') { pattern++; if (*pattern == '}') pattern++; } } } else { while ((*pattern != '}') && (*pattern != ',') && (*pattern != '\0')) { pattern++; if (*pattern == '\\') { pattern++; if ((*pattern == '}') || (*pattern == ',')) pattern++; } } } if (*pattern != '\0') pattern++; } break; } default: { if (*expression != *pattern) done=MagickTrue; else { expression++; pattern++; } } } } while (*pattern == '*') pattern++; return((MagickBooleanType) ((*expression == '\0') && (*pattern == '\0'))); }