]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/xml-tree.c
(no commit message)
[imagemagick] / MagickCore / xml-tree.c
index 14492efa2d89bd4fce9ff548463d0d2061b12dba..e3c8a82acfa1f231bce6c85cc2ed4ad436a3c00d 100644 (file)
 %                              XML Tree Methods                               %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                               December 2004                                 %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -49,6 +49,7 @@
 */
 #include "MagickCore/studio.h"
 #include "MagickCore/blob.h"
+#include "MagickCore/blob-private.h"
 #include "MagickCore/exception.h"
 #include "MagickCore/exception-private.h"
 #include "MagickCore/log.h"
@@ -233,7 +234,8 @@ MagickPrivate XMLTreeInfo *AddPathToXMLTree(XMLTreeInfo *xml_info,
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   node=xml_info;
   components=GetPathComponents(path,&number_components);
   if (components == (char **) NULL)
@@ -456,7 +458,53 @@ static char **DestroyXMLTreeAttributes(char **attributes)
   return((char **) NULL);
 }
 
-MagickExport XMLTreeInfo *DestroyXMLTree(XMLTreeInfo *xml_info)
+static void DestroyXMLTreeChild(XMLTreeInfo *xml_info)
+{
+  XMLTreeInfo
+    *node,
+    *prev;
+
+  node=xml_info->child;
+  while(node != (XMLTreeInfo *) NULL)
+  {
+    prev=(XMLTreeInfo *) NULL;
+    while(node->child != (XMLTreeInfo *) NULL)
+    {
+      prev=node;
+      node=node->child;
+    }
+    (void) DestroyXMLTree(node);
+    if (prev != (XMLTreeInfo* ) NULL)
+      prev->child=(XMLTreeInfo *) NULL;
+    node=prev;
+  }
+  xml_info->child=(XMLTreeInfo *) NULL;
+}
+
+static void DestroyXMLTreeOrdered(XMLTreeInfo *xml_info)
+{
+  XMLTreeInfo
+    *node,
+    *prev;
+
+  node=xml_info->ordered;
+  while(node != (XMLTreeInfo *) NULL)
+  {
+    prev=(XMLTreeInfo *) NULL;
+    while(node->ordered != (XMLTreeInfo *) NULL)
+    {
+      prev=node;
+      node=node->ordered;
+    }
+    (void) DestroyXMLTree(node);
+    if (prev != (XMLTreeInfo* ) NULL)
+      prev->ordered=(XMLTreeInfo *) NULL;
+    node=prev;
+  }
+  xml_info->ordered=(XMLTreeInfo *) NULL;
+}
+
+static void DestroyXMLTreeRoot(XMLTreeInfo *xml_info)
 {
   char
     **attributes;
@@ -473,59 +521,225 @@ MagickExport XMLTreeInfo *DestroyXMLTree(XMLTreeInfo *xml_info)
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
-  if (xml_info->child != (XMLTreeInfo *) NULL)
-    xml_info->child=DestroyXMLTree(xml_info->child);
-  if (xml_info->ordered != (XMLTreeInfo *) NULL)
-    xml_info->ordered=DestroyXMLTree(xml_info->ordered);
-  if (xml_info->parent == (XMLTreeInfo *) NULL)
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->parent != (XMLTreeInfo *) NULL)
+    return;
+  /*
+    Free root tag allocations.
+  */
+  root=(XMLTreeRoot *) xml_info;
+  for (i=NumberPredefinedEntities; root->entities[i] != (char *) NULL; i+=2)
+    root->entities[i+1]=DestroyString(root->entities[i+1]);
+  root->entities=(char **) RelinquishMagickMemory(root->entities);
+  for (i=0; root->attributes[i] != (char **) NULL; i++)
+  {
+    attributes=root->attributes[i];
+    if (attributes[0] != (char *) NULL)
+      attributes[0]=DestroyString(attributes[0]);
+    for (j=1; attributes[j] != (char *) NULL; j+=3)
+    {
+      if (attributes[j] != (char *) NULL)
+        attributes[j]=DestroyString(attributes[j]);
+      if (attributes[j+1] != (char *) NULL)
+        attributes[j+1]=DestroyString(attributes[j+1]);
+      if (attributes[j+2] != (char *) NULL)
+        attributes[j+2]=DestroyString(attributes[j+2]);
+    }
+    attributes=(char **) RelinquishMagickMemory(attributes);
+  }
+  if (root->attributes[0] != (char **) NULL)
+    root->attributes=(char ***) RelinquishMagickMemory(root->attributes);
+  if (root->processing_instructions[0] != (char **) NULL)
+    {
+      for (i=0; root->processing_instructions[i] != (char **) NULL; i++)
+      {
+        for (j=0; root->processing_instructions[i][j] != (char *) NULL; j++)
+          root->processing_instructions[i][j]=DestroyString(
+            root->processing_instructions[i][j]);
+        root->processing_instructions[i][j+1]=DestroyString(
+          root->processing_instructions[i][j+1]);
+        root->processing_instructions[i]=(char **) RelinquishMagickMemory(
+          root->processing_instructions[i]);
+      }
+      root->processing_instructions=(char ***) RelinquishMagickMemory(
+        root->processing_instructions);
+    }
+}
+
+MagickExport XMLTreeInfo *DestroyXMLTree(XMLTreeInfo *xml_info)
+{
+  assert(xml_info != (XMLTreeInfo *) NULL);
+  assert((xml_info->signature == MagickSignature) ||
+         (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  DestroyXMLTreeChild(xml_info);
+  DestroyXMLTreeOrdered(xml_info);
+  DestroyXMLTreeRoot(xml_info);
+  xml_info->attributes=DestroyXMLTreeAttributes(xml_info->attributes);
+  xml_info->content=DestroyString(xml_info->content);
+  xml_info->tag=DestroyString(xml_info->tag);
+  xml_info=(XMLTreeInfo *) RelinquishMagickMemory(xml_info);
+  return((XMLTreeInfo *) NULL);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   F i l e T o X M L                                                         %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  FileToXML() returns the contents of a file as a XML string.
+%
+%  The format of the FileToXML method is:
+%
+%      char *FileToXML(const char *filename,const size_t extent)
+%
+%  A description of each parameter follows:
+%
+%    o filename: the filename.
+%
+%    o extent: Maximum length of the string.
+%
+*/
+
+static inline MagickSizeType MagickMin(const MagickSizeType x,
+  const MagickSizeType y)
+{
+  if (x < y)
+    return(x);
+  return(y);
+}
+
+MagickPrivate char *FileToXML(const char *filename,const size_t extent)
+{
+  char
+    *xml;
+
+  int
+    file;
+
+  MagickOffsetType
+    offset;
+
+  register size_t
+    i;
+
+  size_t
+    length;
+
+  ssize_t
+    count;
+
+  void
+    *map;
+
+  assert(filename != (const char *) NULL);
+  length=0;
+  file=fileno(stdin);
+  if (LocaleCompare(filename,"-") != 0)
+    file=open_utf8(filename,O_RDONLY | O_BINARY,0);
+  if (file == -1)
+    return((char *) NULL);
+  offset=(MagickOffsetType) lseek(file,0,SEEK_END);
+  count=0;
+  if ((file == fileno(stdin)) || (offset < 0) ||
+      (offset != (MagickOffsetType) ((ssize_t) offset)))
     {
+      size_t
+        quantum;
+
+      struct stat
+        file_stats;
+
       /*
-        Free root tag allocations.
+        Stream is not seekable.
       */
-      root=(XMLTreeRoot *) xml_info;
-      for (i=NumberPredefinedEntities; root->entities[i]; i+=2)
-        root->entities[i+1]=DestroyString(root->entities[i+1]);
-      root->entities=(char **) RelinquishMagickMemory(root->entities);
-      for (i=0; root->attributes[i] != (char **) NULL; i++)
+      offset=(MagickOffsetType) lseek(file,0,SEEK_SET);
+      quantum=(size_t) MagickMaxBufferExtent;
+      if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
+        quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
+          MagickMaxBufferExtent);
+      xml=(char *) AcquireQuantumMemory(quantum,sizeof(*xml));
+      for (i=0; xml != (char *) NULL; i+=count)
       {
-        attributes=root->attributes[i];
-        if (attributes[0] != (char *) NULL)
-          attributes[0]=DestroyString(attributes[0]);
-        for (j=1; attributes[j] != (char *) NULL; j+=3)
-        {
-          if (attributes[j] != (char *) NULL)
-            attributes[j]=DestroyString(attributes[j]);
-          if (attributes[j+1] != (char *) NULL)
-            attributes[j+1]=DestroyString(attributes[j+1]);
-          if (attributes[j+2] != (char *) NULL)
-            attributes[j+2]=DestroyString(attributes[j+2]);
-        }
-        attributes=(char **) RelinquishMagickMemory(attributes);
+        count=read(file,xml+i,quantum);
+        if (count <= 0)
+          {
+            count=0;
+            if (errno != EINTR)
+              break;
+          }
+        if (~((size_t) i) < (quantum+1))
+          {
+            xml=(char *) RelinquishMagickMemory(xml);
+            break;
+          }
+        xml=(char *) ResizeQuantumMemory(xml,i+quantum+1,sizeof(*xml));
+        if ((size_t) (i+count) >= extent)
+          break;
       }
-      if (root->attributes[0] != (char **) NULL)
-        root->attributes=(char ***) RelinquishMagickMemory(root->attributes);
-      if (root->processing_instructions[0] != (char **) NULL)
+      if (LocaleCompare(filename,"-") != 0)
+        file=close(file);
+      if (xml == (char *) NULL)
+        return((char *) NULL);
+      if (file == -1)
         {
-          for (i=0; root->processing_instructions[i] != (char **) NULL; i++)
+          xml=(char *) RelinquishMagickMemory(xml);
+          return((char *) NULL);
+        }
+      length=(size_t) MagickMin(i+count,extent);
+      xml[length]='\0';
+      return(xml);
+    }
+  length=(size_t) MagickMin((MagickSizeType) offset,extent);
+  xml=(char *) NULL;
+  if (~length >= (MaxTextExtent-1))
+    xml=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*xml));
+  if (xml == (char *) NULL)
+    {
+      file=close(file);
+      return((char *) NULL);
+    }
+  map=MapBlob(file,ReadMode,0,length);
+  if (map != (char *) NULL)
+    {
+      (void) memcpy(xml,map,length);
+      (void) UnmapBlob(map,length);
+    }
+  else
+    {
+      (void) lseek(file,0,SEEK_SET);
+      for (i=0; i < length; i+=count)
+      {
+        count=read(file,xml+i,(size_t) MagickMin(length-i,(MagickSizeType)
+          SSIZE_MAX));
+        if (count <= 0)
           {
-            for (j=0; root->processing_instructions[i][j] != (char *) NULL; j++)
-              root->processing_instructions[i][j]=DestroyString(
-                root->processing_instructions[i][j]);
-            root->processing_instructions[i][j+1]=DestroyString(
-              root->processing_instructions[i][j+1]);
-            root->processing_instructions[i]=(char **) RelinquishMagickMemory(
-              root->processing_instructions[i]);
+            count=0;
+            if (errno != EINTR)
+              break;
           }
-          root->processing_instructions=(char ***) RelinquishMagickMemory(
-            root->processing_instructions);
+      }
+      if (i < length)
+        {
+          file=close(file)-1;
+          xml=(char *) RelinquishMagickMemory(xml);
+          return((char *) NULL);
         }
     }
-  xml_info->attributes=DestroyXMLTreeAttributes(xml_info->attributes);
-  xml_info->content=DestroyString(xml_info->content);
-  xml_info->tag=DestroyString(xml_info->tag);
-  xml_info=(XMLTreeInfo *) RelinquishMagickMemory(xml_info);
-  return((XMLTreeInfo *) NULL);
+  xml[length]='\0';
+  if (LocaleCompare(filename,"-") != 0)
+    file=close(file);
+  if (file == -1)
+    xml=(char *) RelinquishMagickMemory(xml);
+  return(xml);
 }
 \f
 /*
@@ -550,12 +764,13 @@ MagickExport XMLTreeInfo *DestroyXMLTree(XMLTreeInfo *xml_info)
 %    o xml_info: the xml info.
 %
 */
-MagickPrivate XMLTreeInfo *GetNextXMLTreeTag(XMLTreeInfo *xml_info)
+MagickExport XMLTreeInfo *GetNextXMLTreeTag(XMLTreeInfo *xml_info)
 {
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   return(xml_info->next);
 }
 \f
@@ -584,7 +799,7 @@ MagickPrivate XMLTreeInfo *GetNextXMLTreeTag(XMLTreeInfo *xml_info)
 %    o tag: the attribute tag.
 %
 */
-MagickPrivate const char *GetXMLTreeAttribute(XMLTreeInfo *xml_info,
+MagickExport const char *GetXMLTreeAttribute(XMLTreeInfo *xml_info,
   const char *tag)
 {
   register ssize_t
@@ -599,7 +814,8 @@ MagickPrivate const char *GetXMLTreeAttribute(XMLTreeInfo *xml_info,
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   if (xml_info->attributes == (char **) NULL)
     return((const char *) NULL);
   i=0;
@@ -661,7 +877,8 @@ MagickPrivate MagickBooleanType GetXMLTreeAttributes(const XMLTreeInfo *xml_info
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((const XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   assert(attributes != (SplayTreeInfo *) NULL);
   if (xml_info->attributes == (char **) NULL)
     return(MagickTrue);
@@ -707,7 +924,8 @@ MagickExport XMLTreeInfo *GetXMLTreeChild(XMLTreeInfo *xml_info,const char *tag)
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   child=xml_info->child;
   if (tag != (const char *) NULL)
     while ((child != (XMLTreeInfo *) NULL) && (strcmp(child->tag,tag) != 0))
@@ -743,7 +961,8 @@ MagickExport const char *GetXMLTreeContent(XMLTreeInfo *xml_info)
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   return(xml_info->content);
 }
 \f
@@ -774,7 +993,8 @@ MagickPrivate XMLTreeInfo *GetXMLTreeOrdered(XMLTreeInfo *xml_info)
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   return(xml_info->ordered);
 }
 \f
@@ -825,7 +1045,8 @@ MagickPrivate XMLTreeInfo *GetXMLTreePath(XMLTreeInfo *xml_info,const char *path
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   node=xml_info;
   components=GetPathComponents(path,&number_components);
   if (components == (char **) NULL)
@@ -889,7 +1110,8 @@ MagickPrivate const char **GetXMLTreeProcessingInstructions(
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   root=(XMLTreeRoot *) xml_info;
   while (root->root.parent != (XMLTreeInfo *) NULL)
     root=(XMLTreeRoot *) root->root.parent;
@@ -929,7 +1151,8 @@ MagickExport XMLTreeInfo *GetXMLTreeSibling(XMLTreeInfo *xml_info)
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   return(xml_info->sibling);
 }
 \f
@@ -960,7 +1183,8 @@ MagickExport const char *GetXMLTreeTag(XMLTreeInfo *xml_info)
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   return(xml_info->tag);
 }
 \f
@@ -1295,7 +1519,8 @@ static char *ParseEntities(char *xml,char **entities,int state)
                   xml=p+offset;
                   entity=strchr(xml,';');
                 }
-              (void) CopyMagickMemory(xml+length,entity+1,strlen(entity));
+              if (entity != (char *) NULL)
+                (void) CopyMagickMemory(xml+length,entity+1,strlen(entity));
               (void) strncpy(xml,entities[i],length);
             }
         }
@@ -1338,7 +1563,7 @@ static void ParseCharacterContent(XMLTreeRoot *root,char *xml,
     return;
   xml[length]='\0';
   xml=ParseEntities(xml,root->entities,state);
-  if (*xml_info->content != '\0')
+  if ((xml_info->content != (char *) NULL) && (*xml_info->content != '\0'))
     {
       (void) ConcatenateString(&xml_info->content,xml);
       xml=DestroyString(xml);
@@ -1383,13 +1608,12 @@ static MagickBooleanType ValidateEntities(char *tag,char *xml,char **entities)
       return(MagickFalse);
     i=0;
     while ((entities[i] != (char *) NULL) &&
-           (strncmp(entities[i],xml+1,strlen(entities[i]) == 0)))
+           (strncmp(entities[i],xml+1,strlen(entities[i])) == 0))
       i+=2;
     if ((entities[i] != (char *) NULL) &&
         (ValidateEntities(tag,entities[i+1],entities) == 0))
       return(MagickFalse);
   }
-  return(MagickTrue);
 }
 
 static void ParseProcessingInstructions(XMLTreeRoot *root,char *xml,
@@ -1460,7 +1684,7 @@ static void ParseProcessingInstructions(XMLTreeRoot *root,char *xml,
     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
   root->processing_instructions[i][j+2]=(char *) ResizeQuantumMemory(
     root->processing_instructions[i][j+1],(size_t) (j+1),
-    sizeof(**root->processing_instructions));
+    sizeof(*root->processing_instructions));
   if (root->processing_instructions[i][j+2] == (char *) NULL)
     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
   (void) CopyMagickString(root->processing_instructions[i][j+2]+j-1,
@@ -1573,6 +1797,7 @@ static MagickBooleanType ParseInternalDoctype(XMLTreeRoot *root,char *xml,
             *xml='\0';
             i=0;
             while ((root->attributes[i] != (char **) NULL) &&
+                   (n != (char *) NULL) &&
                    (strcmp(n,root->attributes[i][0]) != 0))
               i++;
             while ((*(n=xml+strspn(xml+1,XMLWhitespace)+1) != '\0') &&
@@ -1698,7 +1923,8 @@ static void ParseOpenTag(XMLTreeRoot *root,char *tag,char **attributes)
     xml_info->tag=ConstantString(tag);
   else
     xml_info=AddChildToXMLTree(xml_info,tag,strlen(xml_info->content));
-  xml_info->attributes=attributes;
+  if (xml_info != (XMLTreeInfo *) NULL)
+    xml_info->attributes=attributes;
   root->node=xml_info;
 }
 
@@ -1768,8 +1994,9 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
   {
     attributes=(char **) sentinel;
     tag=p;
+    c=(*p);
     if ((isalpha((int) ((unsigned char) *p)) !=0) || (*p == '_') ||
-        (*p == ':') || (((int) *p) < '\0'))
+        (*p == ':') || (c < '\0'))
       {
         /*
           Tag.
@@ -2050,7 +2277,7 @@ MagickExport XMLTreeInfo *NewXMLTree(const char *xml,ExceptionInfo *exception)
       return(&root->root);
     }
   (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
-    "ParseError","unclosed tag: `%s'",root->node->tag);
+    "ParseError","unclosed tag: '%s'",root->node->tag);
   return(&root->root);
 }
 \f
@@ -2141,7 +2368,8 @@ MagickPrivate XMLTreeInfo *PruneTagFromXMLTree(XMLTreeInfo *xml_info)
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   if (xml_info->next != (XMLTreeInfo *) NULL)
     xml_info->next->sibling=xml_info->sibling;
   if (xml_info->parent != (XMLTreeInfo *) NULL)
@@ -2218,7 +2446,8 @@ MagickPrivate XMLTreeInfo *SetXMLTreeAttribute(XMLTreeInfo *xml_info,
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   i=0;
   while ((xml_info->attributes[i] != (char *) NULL) &&
          (strcmp(xml_info->attributes[i],tag) != 0))
@@ -2241,8 +2470,7 @@ MagickPrivate XMLTreeInfo *SetXMLTreeAttribute(XMLTreeInfo *xml_info,
             xml_info->attributes[1]=ConstantString("");
         }
       if (xml_info->attributes == (char **) NULL)
-        ThrowFatalException(ResourceLimitFatalError,
-          "UnableToAcquireString");
+        ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
       xml_info->attributes[i]=ConstantString(tag);
       xml_info->attributes[i+2]=(char *) NULL;
       (void) strlen(xml_info->attributes[i+1]);
@@ -2262,14 +2490,14 @@ MagickPrivate XMLTreeInfo *SetXMLTreeAttribute(XMLTreeInfo *xml_info,
     xml_info->attributes[i]=DestroyString(xml_info->attributes[i]);
   (void) CopyMagickMemory(xml_info->attributes+i,xml_info->attributes+i+2,
     (size_t) (j-i)*sizeof(*xml_info->attributes));
-  j-=2;
   xml_info->attributes=(char **) ResizeQuantumMemory(xml_info->attributes,
     (size_t) (j+2),sizeof(*xml_info->attributes));
   if (xml_info->attributes == (char **) NULL)
     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
+  j-=2;
   (void) CopyMagickMemory(xml_info->attributes[j+1]+(i/2),
-    xml_info->attributes[j+1]+(i/2)+1,(size_t) ((j/2)-(i/2))*
-    sizeof(*xml_info->attributes));
+    xml_info->attributes[j+1]+(i/2)+1,(size_t) (((j+2)/2)-(i/2))*
+    sizeof(**xml_info->attributes));
   return(xml_info);
 }
 \f
@@ -2305,7 +2533,8 @@ MagickExport XMLTreeInfo *SetXMLTreeContent(XMLTreeInfo *xml_info,
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   if (xml_info->content != (char *) NULL)
     xml_info->content=DestroyString(xml_info->content);
   xml_info->content=(char *) ConstantString(content);
@@ -2396,7 +2625,7 @@ static char *XMLTreeTagToXML(XMLTreeInfo *xml_info,char **source,size_t *length,
   if ((*length+strlen(xml_info->tag)+MaxTextExtent) > *extent)
     {
       *extent=(*length)+strlen(xml_info->tag)+MaxTextExtent;
-      *source=(char *) ResizeQuantumMemory(*source,*extent,sizeof(*source));
+      *source=(char *) ResizeQuantumMemory(*source,*extent,sizeof(**source));
       if (*source == (char *) NULL)
         return(*source);
     }
@@ -2505,7 +2734,8 @@ MagickExport char *XMLTreeInfoToXML(XMLTreeInfo *xml_info)
   assert(xml_info != (XMLTreeInfo *) NULL);
   assert((xml_info->signature == MagickSignature) ||
          (((XMLTreeRoot *) xml_info)->signature == MagickSignature));
-  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  if (xml_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
   if (xml_info->tag == (char *) NULL)
     return((char *) NULL);
   xml=AcquireString((char *) NULL);