71 #define NumberPredefinedEntities 10 72 #define XMLWhitespace "\t\r\n " 216 const char *path,
const size_t offset)
243 if (components == (
char **) NULL)
245 for (i=0; i < (ssize_t) number_components; i++)
265 for ( ; i < (ssize_t) number_components; i++)
316 if (utf8 == (
unsigned char *) NULL)
317 return((
char *) NULL);
318 for (p=utf8; *p !=
'\0'; p++)
319 if ((*p < 0x20) && (*p != 0x09) && (*p != 0x0a) && (*p != 0x0d))
326 base64=
Base64Encode(utf8,strlen((
char *) utf8),&length);
328 if (base64 == (
char *) NULL)
329 return((
char *) NULL);
334 return(canonical_content);
338 return(canonical_content);
373 return((
char **) NULL);
374 for (i=0;
attributes[i] != (
char *) NULL; i+=2)
385 return((
char **) NULL);
448 for (i=0; root->
attributes[i] != (
char **) NULL; i++)
453 for (j=1;
attributes[j] != (
char *) NULL; j+=3)
547 assert(filename != (
const char *) NULL);
553 return((
char *) NULL);
556 if ((file == fileno(stdin)) || (
offset < 0) ||
570 if ((fstat(file,&file_stats) == 0) && (file_stats.st_size > 0))
573 for (i=0; xml != (
char *) NULL; i+=count)
575 count=read(file,xml+i,quantum);
582 if (~((
size_t) i) < (quantum+1))
588 if ((
size_t) (i+count) >= extent)
593 if (xml == (
char *) NULL)
594 return((
char *) NULL);
598 return((
char *) NULL);
600 length=(size_t)
MagickMin(i+count,extent);
608 if (xml == (
char *) NULL)
611 return((
char *) NULL);
614 if (map != (
char *) NULL)
616 (void) memcpy(xml,map,length);
621 (void) lseek(file,0,SEEK_SET);
622 for (i=0; i < length; i+=count)
636 return((
char *) NULL);
676 return(xml_info->next);
722 return((
const char *) NULL);
724 while ((xml_info->
attributes[i] != (
char *) NULL) &&
733 while ((root->
attributes[i] != (
char **) NULL) &&
734 (strcmp(root->
attributes[i][0],xml_info->tag) != 0))
737 return((
const char *) NULL);
739 while ((root->
attributes[i][j] != (
char *) NULL) &&
743 return((
const char *) NULL);
788 while (xml_info->
attributes[i] != (
char *) NULL)
831 child=xml_info->child;
832 if (tag != (
const char *) NULL)
833 while ((child != (
XMLTreeInfo *) NULL) && (strcmp(child->
tag,tag) != 0))
868 return(xml_info->content);
900 return(xml_info->ordered);
955 if (components == (
char **) NULL)
957 for (i=0; i < (ssize_t) number_components; i++)
974 for ( ; i < (ssize_t) number_components; i++)
1059 return(xml_info->sibling);
1091 return(xml_info->tag);
1137 xml_info->
child=child;
1140 head=xml_info->
child;
1141 if (head->
offset > offset)
1144 xml_info->
child=child;
1236 if (utf8 == (
char *) NULL)
1237 return((
char *) NULL);
1238 encoding=(*content ==
'\xFE') ? 1 : (*content ==
'\xFF') ? 0 : -1;
1244 (void) memcpy(utf8,content,*length*
sizeof(*utf8));
1250 for (i=2; i < (ssize_t) (*length-1); i+=2)
1252 c=(encoding != 0) ? ((content[i] & 0xff) << 8) | (content[i+1] & 0xff) :
1253 ((content[i+1] & 0xff) << 8) | (content[i] & 0xff);
1254 if ((c >= 0xd800) && (c <= 0xdfff) && ((i+=2) < (ssize_t) (*length-1)))
1256 byte=(encoding != 0) ? ((content[i] & 0xff) << 8) |
1257 (content[i+1] & 0xff) : ((content[i+1] & 0xff) << 8) |
1258 (content[i] & 0xff);
1259 c=(((c & 0x3ff) << 10) | (byte & 0x3ff))+0x10000;
1265 if (utf8 == (
char *) NULL)
1278 for (bits=0; byte != 0; byte/=2)
1281 utf8[j++]=(0xFF << (7-bits)) | (c >> (6*bits));
1285 utf8[j]=0x80 | ((c >> (6*bits)) & 0x3f);
1291 if (utf8 != (
char *) NULL)
1324 for ( ; *xml !=
'\0'; xml++)
1325 while (*xml ==
'\r')
1329 (void) memmove(xml,xml+1,strlen(xml));
1333 while ((*xml !=
'\0') && (*xml !=
'&') && ((*xml !=
'%') ||
1334 (state !=
'%')) && (isspace((
int) ((
unsigned char) *xml) == 0)))
1346 if ((state !=
'c') && (strncmp(xml,
"&#",2) == 0))
1352 c=strtol(xml+2,&entity,10);
1354 c=strtol(xml+3,&entity,16);
1355 if ((c == 0) || (*entity !=
';'))
1371 for (i=0; byte != 0; byte/=2)
1374 *xml=(char) ((0xFF << (7-i)) | (c >> (6*i)));
1379 *xml=(char) (0x80 | ((c >> (6*i)) & 0x3F));
1383 (void) memmove(xml,strchr(xml,
';')+1,strlen(strchr(xml,
';')));
1386 if (((*xml ==
'&') && ((state ==
'&') || (state ==
' ') ||
1387 (state ==
'*'))) || ((state ==
'%') && (*xml ==
'%')))
1393 while ((entities[i] != (
char *) NULL) &&
1394 (strncmp(xml+1,entities[i],strlen(entities[i])) != 0))
1396 if (entities[i++] == (
char *) NULL)
1399 if (entities[i] != (
char *) NULL)
1404 length=strlen(entities[i]);
1405 entity=strchr(xml,
';');
1406 if ((entity != (
char *) NULL) &&
1407 ((length-1L) >= (
size_t) (entity-xml)))
1409 offset=(ssize_t) (xml-p);
1410 extent=(size_t) (offset+length+strlen(entity));
1422 sizeof(*extent_xml));
1423 if (extent_xml != (
char *) NULL)
1425 memset(extent_xml,0,extent*
sizeof(*extent_xml));
1427 sizeof(*extent_xml));
1431 if (p == (
char *) NULL)
1433 "MemoryAllocationFailed");
1435 entity=strchr(xml,
';');
1437 if (entity != (
char *) NULL)
1438 (void) memmove(xml+length,entity+1,strlen(entity));
1439 (void) memcpy(xml,entities[i],length);
1443 if (((state ==
' ') || (state ==
'*')) &&
1444 (isspace((
int) ((
unsigned char) *xml) != 0)))
1454 for (xml=p; *xml !=
'\0'; xml++)
1459 i=(ssize_t) strspn(xml,accept);
1461 (void) memmove(xml,xml+i,strlen(xml+i)+1);
1462 while ((*xml !=
'\0') && (*xml !=
' '))
1468 if ((xml >= p) && (*xml ==
' '))
1475 const size_t length,
const char state)
1480 xml_info=root->
node;
1481 if ((xml_info == (
XMLTreeInfo *) NULL) || (xml_info->
tag == (
char *) NULL) ||
1486 if ((xml_info->
content != (
char *) NULL) && (*xml_info->
content !=
'\0'))
1493 if (xml_info->
content != (
char *) NULL)
1503 (root->
node->
tag == (
char *) NULL) || (strcmp(tag,root->
node->
tag) != 0))
1506 "ParseError",
"unexpected closing tag </%s>",tag);
1507 return(&root->
root);
1514 const size_t depth,
char **entities)
1526 while ((*xml !=
'\0') && (*xml !=
'&'))
1530 if (strncmp(xml+1,tag,strlen(tag)) == 0)
1533 while ((entities[i] != (
char *) NULL) &&
1534 (strncmp(entities[i],xml+1,strlen(entities[i])) == 0))
1536 if ((entities[i] != (
char *) NULL) &&
1562 if (strcmp(target,
"xml") == 0)
1564 xml=strstr(xml,
"standalone");
1565 if ((xml != (
char *) NULL) &&
1566 (strncmp(xml+strspn(xml+10,
XMLWhitespace "='\"")+10,
"yes",3) == 0))
1612 root->
root.
tag != (
char *) NULL ?
">" :
"<",2);
1624 **predefined_entitites,
1637 if (predefined_entitites == (
char **) NULL)
1640 for (xml[length]=
'\0'; xml != (
char *) NULL; )
1642 while ((*xml !=
'\0') && (*xml !=
'<') && (*xml !=
'%'))
1646 if ((strlen(xml) > 9) && (strncmp(xml,
"<!ENTITY",8) == 0))
1656 if ((isalpha((
int) ((
unsigned char) *n)) == 0) && (*n !=
'_'))
1665 if ((q !=
'"') && (q !=
'\''))
1670 xml=strchr(xml,
'>');
1673 entities=(*c ==
'%') ? predefined_entitites : root->
entities;
1674 for (i=0; entities[i] != (
char *) NULL; i++) ;
1677 if (entities == (
char **) NULL)
1680 predefined_entitites=entities;
1686 if (xml != (
char *) NULL)
1692 entities[i+2]=(
char *) NULL;
1697 if (entities[i+1] != v)
1700 OptionWarning,
"ParseError",
"circular entity declaration &%s",n);
1702 predefined_entitites);
1707 if (strncmp(xml,
"<!ATTLIST",9) == 0)
1718 predefined_entitites);
1726 while ((root->
attributes[i] != (
char **) NULL) &&
1727 (n != (
char *) NULL) &&
1741 predefined_entitites);
1745 c=(
char *) (strncmp(xml,
"CDATA",5) != 0 ?
"*" :
" ");
1746 if (strncmp(xml,
"NOTATION",8) == 0)
1748 xml=(*xml ==
'(') ? strchr(xml,
')') : xml+
1750 if (xml == (
char *) NULL)
1755 predefined_entitites);
1759 if (strncmp(xml,
"#FIXED",6) == 0)
1769 if (((*xml ==
'"') || (*xml ==
'\'')) &&
1770 ((xml=strchr(v=xml+1,*xml)) != (
char *) NULL))
1777 predefined_entitites);
1794 "MemoryAllocationFailed");
1799 "MemoryAllocationFailed");
1804 for (j=1; root->
attributes[i][j] != (
char *) NULL; j+=3) ;
1809 "MemoryAllocationFailed");
1813 if (v != (
char *) NULL)
1819 if (strncmp(xml,
"<!--", 4) == 0)
1820 xml=strstr(xml+4,
"-->");
1822 if (strncmp(xml,
"<?", 2) == 0)
1826 if (xml != (
char *) NULL)
1834 xml=strchr(xml,
'>');
1848 xml_info=root->
node;
1849 if (xml_info->
tag == (
char *) NULL)
1855 root->
node=xml_info;
1916 if ((xml == (
const char *) NULL) || (strlen(xml) == 0))
1919 "ParseError",
"root tag missing");
1925 if (utf8 == (
char *) NULL)
1928 "ParseError",
"UTF16 to UTF8 failed");
1931 terminal=utf8[length-1];
1932 utf8[length-1]=
'\0';
1934 while ((*p !=
'\0') && (*p !=
'<'))
1939 "ParseError",
"root tag missing");
1943 attribute=(
char **) NULL;
1951 if ((isalpha((
int) ((
unsigned char) *p)) != 0) || (*p ==
'_') ||
1952 (*p ==
':') || (c <
'\0'))
1962 return(&root->
root);
1965 while (isspace((
int) ((
unsigned char) *p)) != 0)
1967 if (((isalpha((
int) ((
unsigned char) *p)) != 0) || (*p ==
'_')) &&
1968 (ignore_depth == 0))
1970 if ((*p !=
'\0') && (*p !=
'/') && (*p !=
'>'))
1976 while ((root->
attributes[i] != (
char **) NULL) &&
1981 for (l=0; (*p !=
'\0') && (*p !=
'/') && (*p !=
'>'); l+=2)
1988 sizeof(*attributes));
1991 (l+4),
sizeof(*attributes));
1992 if (attributes == (
char **) NULL)
1997 return(&root->
root);
1999 attributes[l+2]=(
char *) NULL;
2000 attributes[l+1]=(
char *) NULL;
2003 if ((*p !=
'=') && (isspace((
int) ((
unsigned char) *p)) == 0))
2010 if ((c ==
'"') || (c ==
'\''))
2017 while ((*p !=
'\0') && (*p != c))
2030 return(&root->
root);
2033 while ((attribute != (
char **) NULL) &&
2034 (attribute[j] != (
char *) NULL) &&
2035 (strcmp(attribute[j],attributes[l]) != 0))
2038 root->
entities,(attribute != (
char **) NULL) &&
2039 (attribute[j] != (
char *) NULL) ? *attribute[j+2] :
2044 while (isspace((
int) ((
unsigned char) *p)) != 0)
2050 while((*p !=
'\0') && (*p !=
'/') && (*p !=
'>'))
2059 if (((*p !=
'\0') && (*p !=
'>')) ||
2060 ((*p ==
'\0') && (terminal !=
'>')))
2067 return(&root->
root);
2080 if ((*p ==
'>') || ((*p ==
'\0') && (terminal ==
'>')))
2099 return(&root->
root);
2112 if ((c ==
'\0') && (terminal !=
'>'))
2117 return(&root->
root);
2120 if ((ignore_depth == 0) &&
2124 return(&root->
root);
2126 if (ignore_depth > 0)
2129 if (isspace((
int) ((
unsigned char) *p)) != 0)
2133 if (strncmp(p,
"!--",3) == 0)
2139 if ((p == (
char *) NULL) || ((*(p+=2) !=
'>') && (*p !=
'\0')) ||
2140 ((*p ==
'\0') && (terminal !=
'>')))
2145 return(&root->
root);
2149 if (strncmp(p,
"![CDATA[",8) == 0)
2155 if (p != (
char *) NULL)
2158 if (ignore_depth == 0)
2166 return(&root->
root);
2170 if (strncmp(p,
"!DOCTYPE",8) == 0)
2175 for (l=0; (*p !=
'\0') && (((l == 0) && (*p !=
'>')) ||
2176 ((l != 0) && ((*p !=
']') ||
2178 l=(ssize_t) ((*p ==
'[') ? 1 : l))
2179 p+=strcspn(p+1,
"[]>")+1;
2180 if ((*p ==
'\0') && (terminal !=
'>'))
2185 return(&root->
root);
2188 tag=strchr(tag,
'[')+1;
2196 return(&root->
root);
2210 if (p == (
char *) NULL)
2213 }
while ((*p !=
'\0') && (*p !=
'>'));
2214 if ((p == (
char *) NULL) || ((*p ==
'\0') &&
2220 return(&root->
root);
2229 return(&root->
root);
2231 if ((p == (
char *) NULL) || (*p ==
'\0'))
2235 if ((*p !=
'\0') && (*p !=
'<'))
2240 while ((*p !=
'\0') && (*p !=
'<'))
2244 if (ignore_depth == 0)
2253 return(&root->
root);
2254 if (root->
node->
tag == (
char *) NULL)
2257 "ParseError",
"root tag missing");
2258 return(&root->
root);
2261 "ParseError",
"unclosed tag: '%s'",root->
node->
tag);
2262 return(&root->
root);
2292 "lt;",
"<",
"gt;",
">",
"quot;",
""",
2293 "apos;",
"'",
"amp;",
"&", (
char *) NULL
2302 (void) memset(root,0,
sizeof(*root));
2304 if (tag != (
char *) NULL)
2309 if (root->
entities == (
char **) NULL)
2311 (void) memcpy(root->
entities,predefined_entities,
sizeof(predefined_entities));
2317 return(&root->
root);
2354 xml_info->next->sibling=xml_info->sibling;
2357 node=xml_info->parent->child;
2358 if (node == xml_info)
2359 xml_info->parent->child=xml_info->ordered;
2362 while (node->
ordered != xml_info)
2365 node=xml_info->parent->child;
2366 if (strcmp(node->
tag,xml_info->tag) != 0)
2368 while (strcmp(node->
sibling->
tag,xml_info->tag) != 0)
2370 if (node->
sibling != xml_info)
2377 (node->
next != xml_info))
2418 const char *tag,
const char *value)
2432 while ((xml_info->
attributes[i] != (
char *) NULL) &&
2435 if (xml_info->
attributes[i] == (
char *) NULL)
2440 if (value == (
const char *) NULL)
2461 for (j=i; xml_info->
attributes[j] != (
char *) NULL; j+=2) ;
2462 if (xml_info->
attributes[i+1] != (
char *) NULL)
2464 if (value != (
const char *) NULL)
2469 if (xml_info->
attributes[i] != (
char *) NULL)
2474 (
size_t) (j+2),
sizeof(*xml_info->
attributes));
2479 (i/2)+1,(
size_t) (((j+2)/2)-(i/2))*
sizeof(**xml_info->
attributes));
2510 const char *content)
2517 if (xml_info->content != (
char *) NULL)
2560 content[offset]=
'\0';
2564 if (canonical_content == (
char *) NULL)
2565 return(*destination);
2570 sizeof(**destination));
2571 if (*destination == (
char *) NULL)
2572 return(*destination);
2577 return(*destination);
2581 size_t *extent,
size_t start,
char ***attributes)
2598 content=(
char *)
"";
2608 if (*source == (
char *) NULL)
2621 if (*source == (
char *) NULL)
2622 return((
char *) NULL);
2631 while ((attributes[i] != (
char **) NULL) &&
2632 (strcmp(attributes[i][0],xml_info->
tag) != 0))
2635 while ((attributes[i] != (
char **) NULL) &&
2636 (attributes[i][j] != (
char *) NULL))
2638 if ((attributes[i][j+1] == (
char *) NULL) ||
2648 if (*source == (
char *) NULL)
2649 return((
char *) NULL);
2669 if (*source == (
char *) NULL)
2670 return((
char *) NULL);
2672 if (*xml_info->
content !=
'\0')
2675 while ((offset < xml_info->offset) && (content[offset] !=
'\0'))
2718 if (xml_info->tag == (
char *) NULL)
2719 return((
char *) NULL);
2726 parent=xml_info->parent;
2735 for (j=1; p != (
char *) NULL; j++)
2747 if (xml == (
char *) NULL)
2751 *p !=
'\0' ?
" " :
"",p);
2755 ordered=xml_info->ordered;
2759 xml_info->parent=parent;
2760 xml_info->ordered=ordered;
2769 for (j=1; p != (
char *) NULL; j++)
2781 if (xml == (
char *) NULL)
2785 *p !=
'\0' ?
" " :
"",p);
MagickExport XMLTreeInfo * AddChildToXMLTree(XMLTreeInfo *xml_info, const char *tag, const size_t offset)
#define MagickMaxRecursionDepth
MagickExport XMLTreeInfo * DestroyXMLTree(XMLTreeInfo *xml_info)
MagickExport MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree, const void *key, const void *value)
char *** processing_instructions
MagickExport char * XMLTreeInfoToXML(XMLTreeInfo *xml_info)
#define ThrowFatalException(severity, tag)
SemaphoreInfo * semaphore
MagickExport XMLTreeInfo * GetNextXMLTreeTag(XMLTreeInfo *xml_info)
MagickPrivate XMLTreeInfo * GetXMLTreePath(XMLTreeInfo *xml_info, const char *path)
MagickBooleanType standalone
MagickPrivate MagickBooleanType GetXMLTreeAttributes(const XMLTreeInfo *xml_info, SplayTreeInfo *attributes)
MagickPrivate char * CanonicalXMLContent(const char *content, const MagickBooleanType pedantic)
#define MagickMaxBufferExtent
MagickExport ssize_t FormatLocaleString(char *magick_restrict string, const size_t length, const char *magick_restrict format,...)
MagickExport size_t CopyMagickString(char *magick_restrict destination, const char *magick_restrict source, const size_t length)
static char * ConvertUTF16ToUTF8(const char *content, size_t *length)
static long StringToLong(const char *magick_restrict value)
MagickExport void * ResizeQuantumMemory(void *memory, const size_t count, const size_t quantum)
MagickExport XMLTreeInfo * GetXMLTreeChild(XMLTreeInfo *xml_info, const char *tag)
#define NumberPredefinedEntities
static char ** DestroyXMLTreeAttributes(char **attributes)
MagickExport const char * GetXMLTreeTag(XMLTreeInfo *xml_info)
#define MagickCoreSignature
static XMLTreeInfo * ParseCloseTag(XMLTreeRoot *root, char *tag, ExceptionInfo *exception)
MagickExport void GetPathComponent(const char *path, PathType type, char *component)
MagickExport char * AcquireString(const char *source)
MagickExport void * AcquireCriticalMemory(const size_t size)
MagickPrivate XMLTreeInfo * InsertTagIntoXMLTree(XMLTreeInfo *xml_info, XMLTreeInfo *child, const size_t offset)
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
static char * EncodePredefinedEntities(const char *source, ssize_t offset, char **destination, size_t *length, size_t *extent, MagickBooleanType pedantic)
MagickExport char * Base64Encode(const unsigned char *blob, const size_t blob_length, size_t *encode_length)
static char * SubstituteXMLEntities(const char *content, const MagickBooleanType pedantic)
static void ParseOpenTag(XMLTreeRoot *root, char *tag, char **attributes)
MagickExport const char * GetXMLTreeContent(XMLTreeInfo *xml_info)
MagickPrivate char * FileToXML(const char *filename, const size_t extent)
static char * XMLTreeTagToXML(XMLTreeInfo *xml_info, char **source, size_t *length, size_t *extent, size_t start, char ***attributes)
MagickExport MagickBooleanType IsEventLogging(void)
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
MagickPrivate XMLTreeInfo * PruneTagFromXMLTree(XMLTreeInfo *xml_info)
static int open_utf8(const char *path, int flags, mode_t mode)
static MagickBooleanType ParseInternalDoctype(XMLTreeRoot *root, char *xml, size_t length, ExceptionInfo *exception)
MagickPrivate char ** GetPathComponents(const char *, size_t *)
MagickPrivate XMLTreeInfo * GetXMLTreeOrdered(XMLTreeInfo *xml_info)
MagickExport int LocaleCompare(const char *p, const char *q)
MagickPrivate XMLTreeInfo * AddPathToXMLTree(XMLTreeInfo *xml_info, const char *path, const size_t offset)
#define GetMagickModule()
MagickExport XMLTreeInfo * GetXMLTreeSibling(XMLTreeInfo *xml_info)
static void ParseProcessingInstructions(XMLTreeRoot *root, char *xml, size_t length)
MagickExport const char * GetXMLTreeAttribute(XMLTreeInfo *xml_info, const char *tag)
static char * ParseEntities(char *xml, char **entities, int state)
static void DestroyXMLTreeChild(XMLTreeInfo *xml_info)
MagickExport XMLTreeInfo * SetXMLTreeContent(XMLTreeInfo *xml_info, const char *content)
MagickExport XMLTreeInfo * NewXMLTreeTag(const char *tag)
MagickExport char * DestroyString(char *string)
MagickExport void * AcquireMagickMemory(const size_t size)
static const char * ignore_tags[3]
static MagickBooleanType IsSkipTag(const char *tag)
MagickExport MagickBooleanType ConcatenateString(char **magick_restrict destination, const char *magick_restrict source)
MagickExport void * RelinquishMagickMemory(void *memory)
MagickExport MagickBooleanType UnmapBlob(void *, const size_t)
static void DestroyXMLTreeOrdered(XMLTreeInfo *xml_info)
static void ParseCharacterContent(XMLTreeRoot *root, char *xml, const size_t length, const char state)
MagickPrivate const char ** GetXMLTreeProcessingInstructions(XMLTreeInfo *xml_info, const char *target)
static unsigned char * ConvertLatin1ToUTF8(const unsigned char *magick_restrict content)
SemaphoreInfo * semaphore
MagickExport char * ConstantString(const char *source)
MagickExport XMLTreeInfo * NewXMLTree(const char *xml, ExceptionInfo *exception)
static MagickBooleanType ValidateEntities(char *tag, char *xml, const size_t depth, char **entities)
static void DestroyXMLTreeRoot(XMLTreeInfo *xml_info)
MagickExport void * MapBlob(int, const MapMode, const MagickOffsetType, const size_t)
MagickPrivate XMLTreeInfo * SetXMLTreeAttribute(XMLTreeInfo *xml_info, const char *tag, const char *value)